What happened?
Google Play Console reports a production crash cluster: android.app.RemoteServiceException$ForegroundServiceDidNotStopInTimeException, surfaced via ActivityThread.generateForegroundServiceDidNotStopInTimeException.
- The process crashes on the main thread; the published stack trace contains no app frames (framework only). Play / Logcat should include a message naming the service, e.g.
A foreground service of type dataSync did not stop within its timeout: to.bitkit.androidServices.LightningNodeService — confirm in Play UI if not visible in export.
- Suspected component:
LightningNodeService (AndroidManifest.xml: android:foregroundServiceType="dataSync").
- Play Vitals (60-day window): ~22% of top crash events (~35 events, ~18 affected users); heavily version 181 (2.2.0) (~15 events) with some 180 (2.1.2) and 177 (2.0.3).
- Android versions: almost exclusively Android 15 (SDK 35) and Android 16 Beta (SDK 36).
- Mostly foreground (user-perceived); mixed OEMs.
Likely mechanism: on API 35+, when the system calls Service.onTimeout(), the app must call stopSelf() / stopForeground() within a few seconds. LightningNodeService.onTimeout() (in v2.2.0) runs lightningRepo.stop() then stopSelf() inside serviceScope.launch — node teardown can exceed the system grace period. Same async pattern exists for notification Stop action (ACTION_STOP_SERVICE_AND_APP).
Expected behavior
When the system ends the dataSync foreground service time limit (or user stops the service), the app must stop the foreground service immediately and must not crash with ForegroundServiceDidNotStopInTimeException. Long-running Lightning node shutdown may continue after the service has left foreground state, if needed.
Steps to Reproduce
- Android 15 or 16 device (physical).
- Mainnet wallet, notifications enabled so
LightningNodeService runs (persistent node notification).
- Leave app in background with node service active for an extended period (hours / overnight) to hit
dataSync 6h / 24h limit, or trigger stop paths under time pressure.
- Optional: tap Stop on the node notification.
- Capture Logcat; confirm exception message names
LightningNodeService and dataSync.
No deterministic QA repro confirmed yet.
Logs / Screenshots / Recordings
Play Console: Vitals → Crashes → ForegroundServiceDidNotStopInTimeException.
Exception android.app.RemoteServiceException$ForegroundServiceDidNotStopInTimeException:
at android.app.ActivityThread.generateForegroundServiceDidNotStopInTimeException (ActivityThread.java:2684)
at android.app.ActivityThread.throwRemoteServiceException (ActivityThread.java:2646)
at android.app.ActivityThread.-$$Nest$mthrowRemoteServiceException (Unknown Source)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:3068)
at android.os.Handler.dispatchMessage (Handler.java:110)
at android.os.Looper.loopOnce (Looper.java:273)
at android.os.Looper.loop (Looper.java:363)
at android.app.ActivityThread.main (ActivityThread.java:10060)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:632)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)
Play report: https://play.google.com/console/u/1/developers/5690237613698939049/app/4973032799696771282/vitals/crashes/bd25b8e7e0ecc4cbe7fb6f9c944a39ce/details?isUserPerceived=true&days=60
Bitkit Version
2.2.0 (version code 181), mainnet to.bitkit. Shipped tag v2.2.0 (2026-04-07), targetSdk = 36.
Device / OS
Android 15 (SDK 35), Android 16 Beta (SDK 36). Example devices: Samsung A16, A17x, HMD LGR, others.
Reproducibility
Sometimes (<50%)
Additional context
Suggested fix: in onTimeout (and stop action), call stopForeground(STOP_FOREGROUND_REMOVE) and stopSelf() synchronously on the timeout/stop path, then run lightningRepo.stop() asynchronously.
Review persistent 24/7 dataSync FGS vs WakeNodeWorker — related to #443.
References:
What happened?
Google Play Console reports a production crash cluster:
android.app.RemoteServiceException$ForegroundServiceDidNotStopInTimeException, surfaced viaActivityThread.generateForegroundServiceDidNotStopInTimeException.A foreground service of type dataSync did not stop within its timeout: to.bitkit.androidServices.LightningNodeService— confirm in Play UI if not visible in export.LightningNodeService(AndroidManifest.xml:android:foregroundServiceType="dataSync").Likely mechanism: on API 35+, when the system calls
Service.onTimeout(), the app must callstopSelf()/stopForeground()within a few seconds.LightningNodeService.onTimeout()(in v2.2.0) runslightningRepo.stop()thenstopSelf()insideserviceScope.launch— node teardown can exceed the system grace period. Same async pattern exists for notification Stop action (ACTION_STOP_SERVICE_AND_APP).Expected behavior
When the system ends the
dataSyncforeground service time limit (or user stops the service), the app must stop the foreground service immediately and must not crash withForegroundServiceDidNotStopInTimeException. Long-running Lightning node shutdown may continue after the service has left foreground state, if needed.Steps to Reproduce
LightningNodeServiceruns (persistent node notification).dataSync6h / 24h limit, or trigger stop paths under time pressure.LightningNodeServiceanddataSync.No deterministic QA repro confirmed yet.
Logs / Screenshots / Recordings
Play Console: Vitals → Crashes →
ForegroundServiceDidNotStopInTimeException.Play report: https://play.google.com/console/u/1/developers/5690237613698939049/app/4973032799696771282/vitals/crashes/bd25b8e7e0ecc4cbe7fb6f9c944a39ce/details?isUserPerceived=true&days=60
Bitkit Version
2.2.0 (version code 181), mainnet
to.bitkit. Shipped tagv2.2.0(2026-04-07),targetSdk = 36.Device / OS
Android 15 (SDK 35), Android 16 Beta (SDK 36). Example devices: Samsung A16, A17x, HMD LGR, others.
Reproducibility
Sometimes (<50%)
Additional context
Suggested fix: in
onTimeout(and stop action), callstopForeground(STOP_FOREGROUND_REMOVE)andstopSelf()synchronously on the timeout/stop path, then runlightningRepo.stop()asynchronously.Review persistent 24/7
dataSyncFGS vsWakeNodeWorker— related to #443.References: