SIGABRT crash while using client-sdk-android

We are observing a native crash related to the LiveKit/WebRTC library on Android 7.1.2 devices.
The crash occurs inside libjingle_peerconnection_so.so and terminates with SIGABRT.

From the stack trace, the crash appears to originate from the native WebRTC layer used by the LiveKit Android SDK.

We are not able to reproduce the issue consistently, but it has been reported from production devices.

Crash snippet:

SIGABRT
libjingle_peerconnection_so.so
Android 7.1.2
Device model: Zentron_21

Issue added in git - SIGABRT crash · Issue #940 · livekit/client-sdk-android · GitHub

@Jignesh_Brahmkhatri, This is not a device-specific issue. The SDK’s minSdkVersion is 21, so Android 7.1.2 (API 25) is supported, and v2.25.3 still bundles io.github.webrtc-sdk:android-prefixed:144.7559.05 which produces the libjingle_peerconnection_so.so in your trace.

The same crash class is already open across #940, #951, #332, #343, #360 (closed: #553). #951’s logcat caught the abort site that #940 doesn’t expose: Fatal error in: sdk/android/src/jni/jvm.cc, line 81.

Check failed: false. That sits inside WebRTC’s HandleException, which aborts via RTC_CHECK(false) after ExceptionDescribe() whenever a Java method invoked from @CalledByNative throws an unhandled exception. Both #940 and #951 land on network_thread.

#553 was resolved with a ProGuard keep on org.webrtc.** and livekit.**. The SDK’s consumer-rules.pro already pins those, but RN / Expo / Capacitor wrappers don’t always carry consumer rules into the final release build.

To make #940 actionable, attach to the issue:

• Exact SDK version
• Whether release runs R8 / minify, and whether a non-minified debug build reproduces
• The E rtc : and E AndroidRuntime lines just before the abort (the original Java exception name is printed there by ExceptionDescribe())
• Whether the crash correlates with a specific action (room connect, track publish, simulcast on, mic / camera grant)

@Muhammad_Usman_Bashir Thanks for the reply.

  1. Exact SDK version - 2.25.2 and we also tried with 2.25.3 but same crash happened on both randomly.
  2. Production build is not R8 in which it crashed but we were able to replicate even with R8 in debug.
  3. 2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W android.net.ConnectivityManager$TooManyRequestsException
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at android.net.ConnectivityManager.convertServiceException(ConnectivityManager.java:4165)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at android.net.ConnectivityManager.sendRequestForNetwork(ConnectivityManager.java:4357)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at android.net.ConnectivityManager.sendRequestForNetwork(ConnectivityManager.java:4364)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at android.net.ConnectivityManager.registerNetworkCallback(ConnectivityManager.java:4746)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at android.net.ConnectivityManager.registerNetworkCallback(ConnectivityManager.java:4716)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at livekit.org.webrtc.NetworkMonitorAutoDetect$ConnectivityManagerDelegate.registerNetworkCallback(NetworkMonitorAutoDetect.java:468)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at livekit.org.webrtc.NetworkMonitorAutoDetect.(NetworkMonitorAutoDetect.java:681)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at livekit.org.webrtc.NetworkMonitor$1.create(NetworkMonitor.java:52)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at livekit.org.webrtc.NetworkMonitor.createNetworkChangeDetector(NetworkMonitor.java:195)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at livekit.org.webrtc.NetworkMonitor.startMonitoring(NetworkMonitor.java:110)
    2026-06-05 13:46:16.494 11935-14833 System.err com.gmp.displayapp.debug W at livekit.org.webrtc.NetworkMonitor.startMonitoring(NetworkMonitor.java:140)
    2026-06-05 13:46:16.494 11935-14833 rtc com.gmp.displayapp.debug E #
    # Fatal error in: ../../../sdk/android/src/jni/jvm.cc, line 81
    # last system error: 0
    # Check failed: false
    #
    2026-06-05 13:46:16.651 11935-11980 System.out com.gmp.displayapp.debug I LIVEKIT_REPLAY deferring KIOSK_HOME until +6s after barrier open
    --------- beginning of crash
    2026-06-05 13:46:16.812 11935-14833 libc com.gmp.displayapp.debug A Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 14833 (network_thread ), pid 11935 (isplayapp.debug)
  4. We do not know right now whether its on room connect or track publish but as soon as we try to tap on the button from which livekit is getting initialized and room is being connected, at that time its crashing. The difference here is we create new room everytime.

@Jignesh_Brahmkhatri, That logcat is the actual root cause. The android.net.ConnectivityManager$TooManyRequestsException thrown from livekit.org.webrtc.NetworkMonitorAutoDetect.registerNetworkCallback is the unhandled exception that WebRTC’s native JNI aborts on at jvm.cc:81. Not a ProGuard issue.

Android has a per-process limit on active network callbacks; exceeding it throws this exception. The LK Android SDK registers one callback per Room lifecycle in NetworkMonitor.startMonitoring(), and unregisters it in Room.handleDisconnect() via networkCallbackManager.unregisterCallback() [ livekit/client-sdk-android Room.kt#L1014 ]. Your “we create new room everytime” lines up exactly with this: if the old Room isn’t released, its callback stays registered, callbacks accumulate across taps, and the next Room’s registerNetworkCallback throws inside JNI.

Fix is to call release() on the previous Room before creating a new one:

  // Before creating a new Room, release the old one
  oldRoom?.release()
  // release() triggers handleDisconnect() which calls
  // networkCallbackManager.unregisterCallback() and frees the slot

  // then proceed with creating + connecting your new Room

Room.release() is the documented one-shot teardown: “Once called, this room object must not be used to connect to a server and a new one must be created” [ Room.kt#L658-L667 ].

Architecturally cleaner: reuse a single Room instance, calling disconnect() and connect() to switch sessions rather than constructing a new Room each tap. That sidesteps the cleanup race entirely.

To make #940 actionable now, update with the TooManyRequestsException Java stacktrace from this logcat, your Room-per-tap pattern, and confirmation you weren’t releasing the previous Room. That converts it from “intermittent native crash” to “missing-release lifecycle pattern” which triages much faster.

I usually like to capture the logcat this way because it provide some other helpful critical information that can make these sorts of issues easier to diagnose.

adb logcat -v threadtime > logcat_output.txt.

You can attach that to the issue or DM me and we can take a look.

That last paste seems helpful.

What’s happening

The crash isn’t a minification problem. Look at the lines right before the abort:

android.net.ConnectivityManager$TooManyRequestsException
  at ConnectivityManager.registerNetworkCallback(...)
  at livekit.org.webrtc.NetworkMonitorAutoDetect.<init>(...)
  at livekit.org.webrtc.NetworkMonitor.startMonitoring(...)
rtc E  # Fatal error in: jvm.cc, line 81 # Check failed: false
libc A Fatal signal 6 (SIGABRT) ... network_thread

Android limits how many active network callbacks an app can register at once (about 100 per app). WebRTC registers a couple of these every time it starts monitoring the network, and it unregisters them only when that connection is fully torn down. When the app crosses the limit, registerNetworkCallback throws TooManyRequestsException. Because this happens inside a native WebRTC call, the unhandled exception turns into a hard SIGABRT instead of a normal error. That’s the crash you’re seeing on network_thread.

Why it’s intermittent and hard to reproduce

You mentioned the important detail: “we create a new room every time.” That’s the trigger. Each new Room registers more network callbacks, and if the previous room isn’t fully released, those callbacks leak. After ~100 connect cycles, the next connect tips over the limit and crashes. That’s why it only shows up in production after the app has been running a while, and never on a clean test.

The fix

Make sure every Room is fully released before you create the next one:

  • Call room.disconnect() and release the room object (don’t just drop the reference and create a new one).
  • Even better: create one Room once and reuse it — call connect() / disconnect() on the same instance instead of new Room() on every button tap.

How to confirm it’s the leak

Run this while reconnecting a few times:

adb shell dumpsys connectivity | grep <your.package.name>

You’ll see the registered callback count increase on each connect. If it keeps growing and never drops after you disconnect, the rooms aren’t being released — that’s the leak that eventually causes the crash.

Once that’s fixed, the SIGABRT should stop.