Integration
sentry-android
Build System
Gradle
AGP Version
8.6.0
Proguard
Disabled
Other Error Monitoring Solution
No
Version
8.41.3
Steps to Reproduce
SentryAndroid.init with Session Replay enabled (e.g. sessionSampleRate = 1.0) — ReplayIntegration registers as a connection status observer and AndroidConnectionStatusProvider
registers a ConnectivityManager network callback.
- Call
Sentry.close() from the main thread shortly after init (or whenever a connectivity notification is in flight — Android delivers the current network state immediately after
callback registration, so closing soon after init hits this reliably).
- Race: loop init→close with replay enabled on a loaded emulator; reproduces within ~30 cycles.
Expected Result
Sentry.close() completes and the SDK shuts down cleanly.
Actual Result
Sentry.close() never returns — AB-BA deadlock between ReplayIntegration.lifecycleLock and AndroidConnectionStatusProvider.lock. When close() runs on the main thread this is a permanent
main-thread block (ANR).
- Closing thread:
ReplayIntegration.close() holds lifecycleLock (ReplayIntegration.kt:365) → removeConnectionStatusObserver() waits on the provider lock
(AndroidConnectionStatusProvider.java:441).
- ConnectivityThread:
updateCacheAndNotifyObservers holds the provider lock while notifying observers (AndroidConnectionStatusProvider.java:274) →
ReplayIntegration.onConnectionStatusChanged → resumeInternal() waits on lifecycleLock (ReplayIntegration.kt:220).
"main" Waiting
at io.sentry.android.core.internal.util.AndroidConnectionStatusProvider.removeConnectionStatusObserver(AndroidConnectionStatusProvider.java:441)
at io.sentry.android.replay.ReplayIntegration.close(ReplayIntegration.kt:370)
at io.sentry.Scopes.close(Scopes.java:439)
at io.sentry.Sentry.close(Sentry.java:727)
"ConnectivityThread" Waiting
at io.sentry.android.replay.ReplayIntegration.resumeInternal(ReplayIntegration.kt:220)
at io.sentry.android.replay.ReplayIntegration.onConnectionStatusChanged(ReplayIntegration.kt:393)
at io.sentry.android.core.internal.util.AndroidConnectionStatusProvider$1.updateCacheAndNotifyObservers(AndroidConnectionStatusProvider.java:277)
at io.sentry.android.core.internal.util.AndroidConnectionStatusProvider$1.onCapabilitiesChanged(AndroidConnectionStatusProvider.java:255)
Full thread dump attached: sentry_replay_deadlock_trace.txt
Impact
- CI (ongoing): Recurring 30-minute job timeouts in getsentry/sentry-dart integration tests e.g.
https://github.com/getsentry/sentry-dart/actions/runs/27229728938/job/80406349339
- Production (very rare): Any app with replay enabled that calls
Sentry.close() or re-inits the SDK at runtime can
deadlock if a connectivity change lands in the window. When close() runs on the main thread the result is a permanent ANR caused by the SDK, and the ANR trace is effectively undiagnosable for users — just two parked threads inside io.sentry.*.
- Not affected: apps that never close/re-init Sentry; backgrounding alone is safe (stop() never takes the provider lock).
Integration
sentry-android
Build System
Gradle
AGP Version
8.6.0
Proguard
Disabled
Other Error Monitoring Solution
No
Version
8.41.3
Steps to Reproduce
SentryAndroid.initwith Session Replay enabled (e.g.sessionSampleRate = 1.0) — ReplayIntegration registers as a connection status observer andAndroidConnectionStatusProviderregisters a
ConnectivityManagernetwork callback.Sentry.close()from the main thread shortly after init (or whenever a connectivity notification is in flight — Android delivers the current network state immediately aftercallback registration, so closing soon after init hits this reliably).
Expected Result
Sentry.close() completes and the SDK shuts down cleanly.
Actual Result
Sentry.close()never returns — AB-BA deadlock betweenReplayIntegration.lifecycleLockandAndroidConnectionStatusProvider.lock. Whenclose()runs on the main thread this is a permanentmain-thread block (ANR).
ReplayIntegration.close()holds lifecycleLock (ReplayIntegration.kt:365) →removeConnectionStatusObserver()waits on the provider lock(
AndroidConnectionStatusProvider.java:441).updateCacheAndNotifyObserversholds the provider lock while notifying observers (AndroidConnectionStatusProvider.java:274) →ReplayIntegration.onConnectionStatusChanged→resumeInternal()waits on lifecycleLock (ReplayIntegration.kt:220).Full thread dump attached: sentry_replay_deadlock_trace.txt
Impact
https://github.com/getsentry/sentry-dart/actions/runs/27229728938/job/80406349339
Sentry.close()or re-inits the SDK at runtime candeadlock if a connectivity change lands in the window. When
close()runs on the main thread the result is a permanent ANR caused by the SDK, and the ANR trace is effectively undiagnosable for users — just two parked threads inside io.sentry.*.