# Troubleshooting | Sentry for iOS

Why is Session Replay not running on iOS 26.0?

Due to potential masking issues introduced by Apple's Liquid Glass rendering changes in iOS 26.0, Session Replay is now **automatically disabled** on apps running iOS 26.0+ when built with Xcode 26.0 or later starting with Sentry Cocoa **8.57.0**. This is a defensive measure to protect user privacy and prevent potential PII leaks until masking is reliably supported. Earlier SDK versions do not include this safeguard and may be affected by unreliable masking on iOS 26.0 when built with Xcode 26.0 (Liquid Glass). We recommend upgrading to 8.57.0+ or, if you can't upgrade the SDK, disabling Session Replay manually.

Session Replay will work normally if:

* Your app runs on iOS versions prior to 26.0, OR
* Your app is built with Xcode prior to 26.0, OR
* Your app explicitly sets `UIDesignRequiresCompatibility` to `YES` in `Info.plist`

If you understand the PII risks and want to enable Session Replay anyway, you can override this behavior:

```swift
options.experimental.enableSessionReplayInUnreliableEnvironment = true
```

This experimental override option will be removed in a future minor version once the masking issues are resolved.

You can follow the ongoing work to fix masking for iOS 26.0 (Liquid Glass) in [GitHub issue #6390](https://github.com/getsentry/sentry-cocoa/issues/6390).

Does Session Replay work with UIKit, SwiftUI or AppKit?

Session Replay works with both UIKit and SwiftUI.

Does Session Replay work on macOS, watchOS, tvOS and visionOS?

We don't actively prevent you from using Session Replay on these platforms, but we only officially [support it on iOS](https://docs.sentry.io/platforms/apple/guides/ios/session-replay.md). As a consequence, we can't make guarantees about its functionality and performance on other platforms.

Why are parts of my replay not masked?

Text views, input views, images, video players and webviews are all masked by default. Images with bundled assets aren't masked because the likelihood of these assets containing PII is low. If you encounter a view that should be masked by default, consider opening a [GitHub issue](https://github.com/getsentry/sentry-cocoa/issues).

What's the lowest version of iOS supported?

Session Replay recording happens even on the lowest version supported by the Sentry SDK, which is aligend with appstore support.

Why is my issue missing a replay?

An issue may be missing a replay because the user's device was [offline](https://docs.sentry.io/product/explore/session-replay/mobile.md#frequently-asked-questions) while `sessionSampleRate` was specified, your project/organization was rate-limited, or (in rare cases) the device failed to capture the replay video.

AVFoundation views and layers are not rendered

Session Replay currently cannot capture content from AVFoundation views and layers. This includes:

* `AVPlayerLayer` and other AVFoundation-backed video content
* `AVCaptureVideoPreviewLayer` used for camera previews
* Any media content rendered using AVFoundation components

As a result, camera views, video players, and other AVFoundation-based UI elements will not appear in session replays, even when using `unmaskedViewClasses` configuration.

We are aware of this limitation and are exploring potential solutions to support AVFoundation content in future releases.

You can follow the progress in [this GitHub issue](https://github.com/getsentry/sentry-cocoa/issues/5835).

Photo pickers and camera views are not captured

Session Replay cannot capture photo picker interfaces (`PHPickerViewController` and `UIImagePickerController`) or camera views due to iOS limitations. These pickers use a remote view rendering process rather than being rendered directly in your app's view hierarchy.

On physical devices, photo pickers and camera views will not appear in session replays. On simulators, they may appear because simulators don't use the same remote rendering approach, but this behavior should not be relied upon.

This limitation exists at the iOS system level and cannot be worked around by configuring `unmaskedViewClasses` or other Session Replay settings.

Session Replay is not recording with custom window setup

If you have a custom window setup (e.g., multiple instances of `UIWindow`), you need to ensure that the Sentry SDK is able to find the correct window.

When using window scenes, make sure that the main window is assigned in your `UIWindowSceneDelegate`'s [`window` property](https://developer.apple.com/documentation/uikit/uiwindowscenedelegate/window).

```swift
final class SceneDelegate: NSObject, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let scene = scene as? UIWindowScene else { return }

        // Configure your windows here, e.g.
        let mainWindow = UIWindow(windowScene: scene)
        mainWindow.rootViewController = UIViewController()
        mainWindow.makeKeyAndVisible()

        // Do not forget to assign the window to the SceneDelegate's window property:
        self.window = mainWindow
    }
}
```

Alternatively, you can also create a custom proxy variable for the window:

```swift
final class SceneDelegate: NSObject, UIWindowSceneDelegate {

    var mainWindow: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let scene = scene as? UIWindowScene else { return }

        // Configure your windows here, e.g.
        let mainWindow = UIWindow(windowScene: scene)
        mainWindow.rootViewController = UIViewController()
        mainWindow.makeKeyAndVisible()

        // Do not forget to assign the window to the SceneDelegate's window property:
        self.window = mainWindow
    }

    // This is required to make sure that the Sentry SDK can find the correct window:

    var window: UIWindow? {
        get {
            return mainWindow
        }
        set {
            mainWindow = newValue
        }
    }
}
```

App crashes during Session Replay or screenshot capture

If your app crashes during Session Replay recording or screenshot capture, it may be due to problematic view hierarchies that contain layers that crash when accessed during traversal.

### [Common Causes](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/troubleshooting.md#common-causes)

Some view types contain layers that cause fatal errors when their `sublayers` property is accessed. For example, `CameraUI.ChromeSwiftUIView` on iOS 26+ contains `CameraUI.ModeLoupeLayer` instances that crash during view hierarchy traversal.

### [Solution: Ignore View Types from Subtree Traversal](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/troubleshooting.md#solution-ignore-view-types-from-subtree-traversal)

You can prevent these crashes by configuring the SDK to skip traversing the subtree of problematic view types. The view itself will still be redacted, but the SDK won't attempt to traverse its children, preventing crashes.

To add a problematic view type to the ignore set:

```swift
options.sessionReplay.excludeViewTypeFromSubtreeTraversal("MyProblematicView")
```

The view type identifier uses **partial string matching** against the result of `type(of: view).description()`. This means if you exclude `"MyView"`, it will match `"MyApp.MyView"`, `"MyViewSubclass"`, etc. You can find the exact type name by inspecting the view hierarchy or checking crash logs.

### [Default Protection](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/troubleshooting.md#default-protection)

On iOS 26+, `CameraUI.ChromeSwiftUIView` is automatically included in the ignore set by default to prevent crashes. If you're experiencing crashes with other view types, add them to the ignore set using the method above.

For more information, see the [Ignore View Types from Subtree Traversal](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/customredact.md#ignore-view-types-from-subtree-traversal) section in the custom masking documentation.

Masking limitations with AsyncDisplayKit/Texture

[AsyncDisplayKit](https://github.com/facebookarchive/AsyncDisplayKit) (now archived) and its successor [Texture](https://github.com/texturegroup/texture/) use a custom rendering pipeline that relies on layers rather than standard UIKit components. This architecture prevents Session Replay's default masking options (`maskAllImages` and `maskAllText`) from working correctly.

### [Why masking doesn't work](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/troubleshooting.md#why-masking-doesnt-work)

Texture uses `_ASDisplayView` and `_ASDisplayLayer` classes that forward rendering to associated nodes, rather than using standard UIKit view hierarchies. The SDK's default masking mechanisms rely on identifying standard UIKit components (like `UIImageView` and `UILabel`), which don't exist in Texture's custom rendering pipeline. As a result, content rendered through Texture nodes may not be masked by default.

For example, when inspecting the view hierarchy, you'll see views like `ButtonNode-View` with `_ASDisplayLayer` sublayers rather than standard UIKit components:

```bash
<SentryMaskingExample.ButtonNode-View: 0x103b35e80; node = <SentryMaskingExample.ButtonNode: 0x10483b600>; ...>
   | <_ASDisplayLayer: 0x60000213ab20> (layer)
   | <_ASDisplayLayer: 0x600002139900> (layer)
```

### [Workaround: Mask by view instance](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/troubleshooting.md#workaround-mask-by-view-instance)

You can work around this limitation by using [masking by view instance](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/customredact.md#mask-by-view-instance). Access the `view` property of your `ASDisplayNode` instances and apply masking to those specific views:

```swift
// Access the view from your ASDisplayNode
let nodeView = myASDisplayNode.view
SentrySDK.replay.maskView(view: nodeView)
```

Note that this approach masks entire nodes rather than individual subcomponents. If you need more granular control, you may need to mask parent nodes or use the `supernode` property to mask larger sections of your UI.

### [Other limitations](https://docs.sentry.io/platforms/apple/guides/ios/session-replay/troubleshooting.md#other-limitations)

* Swizzling is not supported. While method swizzling could theoretically intercept `ASImageNode` and `ASTextNode` rendering, Sentry does not support or recommend this approach due to stability and maintenance concerns.
* Layer-backed nodes. Some layer-backed nodes may still not be properly masked even when using view instance masking, as they render directly to layers rather than views.
