Crashlytics OOM Crash — OutOfMemoryError in JsonWriter During Fatal Crash Serialization (No Callback Available to Trim Log for fatal crash)
Summary
Our Flutter application experiences a fatal crash inside Crashlytics itself. Crashlytics fails to serialize the crash event due to an OutOfMemoryError in the JSON encoder.
Because serialization fails:
- Crashlytics never uploads such a crash due to which this crash is arise
- The original crash cause is lost
- The app experiences a second fatal crash caused by Crashlytics
- Flutter cannot intercept or trim logs because no callbacks exist for fatal crashes
This makes the issue impossible to work around from the application side.
Stacktrace
Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 9232 byte allocation with 537312 free bytes and 524KB until OOM, target footprint 268435456, growth limit 268435456; giving up on allocation because <1% of heap free after GC. at java.util.Arrays.copyOf(Arrays.java:3785) at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:182) at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:758) at java.lang.StringBuffer.append(StringBuffer.java:431) at java.io.StringWriter.write(StringWriter.java:77) at android.util.JsonWriter.string(JsonWriter.java:453) at android.util.JsonWriter.value(JsonWriter.java:305) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:170) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:33) at com.google.firebase.encoders.json.JsonDataEncoderBuilder.lambda$static$1(JsonDataEncoderBuilder.java:63) at com.google.firebase.encoders.json.JsonDataEncoderBuilder$$ExternalSyntheticLambda1.encode(D8$$SyntheticClass) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:314) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.internalAddIgnoreNullValues(JsonValueObjectEncoderContext.java:384) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:69) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:110) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventLogEncoder.encode(AutoCrashlyticsReportEncoder.java:588) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventLogEncoder.encode(AutoCrashlyticsReportEncoder.java:580) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.doEncode(JsonValueObjectEncoderContext.java:334) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:309) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.internalAddIgnoreNullValues(JsonValueObjectEncoderContext.java:384) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:69) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:110) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventEncoder.encode(AutoCrashlyticsReportEncoder.java:299) at com.google.firebase.crashlytics.internal.model.AutoCrashlyticsReportEncoder$CrashlyticsReportSessionEventEncoder.encode(AutoCrashlyticsReportEncoder.java:277) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.doEncode(JsonValueObjectEncoderContext.java:334) at com.google.firebase.encoders.json.JsonValueObjectEncoderContext.add(JsonValueObjectEncoderContext.java:309) at com.google.firebase.encoders.json.JsonDataEncoderBuilder$1.encode(JsonDataEncoderBuilder.java:121) at com.google.firebase.encoders.json.JsonDataEncoderBuilder$1.encode(JsonDataEncoderBuilder.java:129) at com.google.firebase.crashlytics.internal.model.serialization.CrashlyticsReportJsonTransform.eventToJson(CrashlyticsReportJsonTransform.java:48) at com.google.firebase.crashlytics.internal.persistence.CrashlyticsReportPersistence.persistEvent(CrashlyticsReportPersistence.java:137) at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator.lambda$persistEvent$0$com-google-firebase-crashlytics-internal-common-SessionReportingCoordinator(SessionReportingCoordinator.java:352) at com.google.firebase.crashlytics.internal.common.SessionReportingCoordinator$$ExternalSyntheticLambda0.run(D8$$SyntheticClass) at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker.lambda$submit$1(CrashlyticsWorker.java:96) at com.google.firebase.crashlytics.internal.concurrency.CrashlyticsWorker$$ExternalSyntheticLambda0.then(D8$$SyntheticClass) at com.google.android.gms.tasks.zze.run(com.google.android.gms:play-services-tasks@@18.1.0:1) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1156) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:651) at com.google.firebase.concurrent.CustomThreadFactory.lambda$newThread$0$com-google-firebase-concurrent-CustomThreadFactory(CustomThreadFactory.java:47) at com.google.firebase.concurrent.CustomThreadFactory$$ExternalSyntheticLambda0.run(D8$$SyntheticClass) at java.lang.Thread.run(Thread.java:1119)
This shows the crash occurs entirely inside Crashlytics while constructing the JSON crash report.
Environment
Flutter Version: (your version used) Android OS: devices with 2–4GB RAM affected. App Type: Real-time CCTV app displaying a new image every second (high memory churn).
FlutterFire Libraries
firebase_analytics: 11.4.4
firebase_core: 3.12.1
firebase_crashlytics: 4.3.1
Crashlytics Android SDK version is auto-managed by FlutterFire.
Behavior Observed
- A fatal crash happens in the app.
- Crashlytics attempts to persist the crash event.
- The JSON encoder (JsonWriter) allocates a very large StringWriter buffer.
- The allocation fails → OutOfMemoryError.
- Crashlytics itself crashes the app again.
- Crash is never uploaded to Firebase.
- didCrashOnPreviousExecution() remains false because persistence never finished.
- Flutter receives no callback, no event, no logs.
This makes it impossible for us to detect, trim, or reduce the crash report.
Why This is a Crashlytics Library Issue
- Crash is happening inside Crashlytics persistence layer
- Developers have no API to intercept, trim, or limit event size
- Crashlytics does not cap JSON event serialization memory
- Crashlytics should never crash the app while trying to log a crash
Targeted Platforms
- Android
I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
Hi @AkashVyasCygnet, thank you for raising the issue. Based on the version you shared, it looks like you're using a year old version.
Could you try using the latest Firebase SDK version and see if the issue persists?
We usually suggests to always use the latest Firebase SDK version to ensure that you have the latest updates and bug fixes that might have been already resolved.
Hey @AkashVyasCygnet. We need more information to resolve this issue but there hasn't been an update in 5 weekdays. I'm marking the issue as stale and if there are no new updates in the next 5 days I will close it automatically.
If you have more information that will help us get to the bottom of this, just add a comment!