When developing modern Android applications, especially those built with complex navigation stacks, fragments, or multiple ViewModels, you may encounter the dreaded:
android.os.TransactionTooLargeException: data parcel size XXX bytes
This error often appears during configuration changes (rotation), navigating between screens, or when an Activity is moving to the background. It typically occurs when the system tries to save the Activity or Fragment state and the bundle being transferred becomes too large.
In this article, we break down why this happens, how to diagnose it, and best practices to prevent it, with real-world examples for Android, Jetpack libraries, Parcelable objects, and even hybrid frameworks such as Flutter, React Native, or Capacitor-based apps.
What Is TransactionTooLargeException in Android?
Android uses an IPC (inter-process communication) mechanism called Binder to pass data between system services and apps. Binder imposes a strict size limit on the parcels sent—typically around 1 MB total per transaction, but practically 250–500 KB depending on the device.
When your Activity is being stopped or destroyed, Android tries to save its UI state into a Bundle. If this bundle becomes too large, the system triggers:
TransactionTooLargeException: data parcel size X bytes
Typical culprits include:
- Extremely large Fragment saved states
- Oversized ViewModel
SavedStateHandle - Passing large objects or arrays via
Intentextras - Storing complex data inside
onSaveInstanceState() - Using Jetpack Navigation or Activity Result APIs with huge state keys
- Libraries saving large UI hierarchies automatically
Understanding the Stacktrace
In your error you might see lines like:
androidx.lifecycle.BundlableSavedStateRegistry.key [size=562156]
android:support:fragments [size=439484]
KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS [size=115992]
This clearly indicates that:
- Jetpack libraries are saving a lot of data in the state bundle.
- Fragment and Activity result registries are quite large.
- Something in the ViewModel or fragment tree is producing massive saved state.
Common Causes and How to Fix Them
Below are the most frequent scenarios that generate oversized saved states—and how to refactor them safely.
1. Storing Large Objects in onSaveInstanceState()
Bad example:
override fun onSaveInstanceState(outState: Bundle) {
outState.putSerializable("products_list", hugeList) // hundreds of KB
}
Why it’s bad
Lists, bitmaps, serialized objects, and network models can easily exceed Android’s limit.
Fix
Only store lightweight data:
outState.putString("lastQuery", currentQuery)
For larger data, use:
- Room database
- SharedPreferences
- Disk cache
- ViewModel (without SavedStateHandle)
- Repository layer
2. Oversized Navigation Component Saved States
Jetpack Navigation automatically stores fragment state.
If fragments contain:
- Large lists in adapters
- StateFlow values with long JSON blobs
- Large arguments passed using
safeArgs - Complex view hierarchies
…then the saved state bundle explodes.
Fix: Disable fragment state saving when you don’t need it
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(null) // ignore previous saved state
}
Or disable state saving for specific fragments:
fragmentManager.saveFragmentInstanceState(fragment)
Or tell NavHostFragment not to save state:
android:saveEnabled="false"
3. Passing Too Much Data via Intents
Problematic example:
val intent = Intent(this, DetailsActivity::class.java)
intent.putExtra("json", largeJsonString) // 300–600 KB
Fix
Pass references, not data:
intent.putExtra("itemId", item.id)
Load the full object from:
- database
- repository
- shared ViewModel
4. Large Parcelable or Serializable Objects
Parcelable models that contain large lists or media objects increase bundle size drastically.
Fix
Avoid sending complete models between screens.
Use caching, local DB, or ViewModels.
5. Large Activity Result API Registry
You may see:
android:support:activity-result [size=122416]
KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS [size=115992]
This means too many Activity Result Launchers are registered dynamically.
Fix
Register launchers outside loops and outside adapters:
private val launcher = registerForActivityResult(...)
6. ViewModel SavedStateHandle Misuse
Bad example
Storing full network responses:
savedStateHandle["response"] = bigJsonString
Fix
Use SavedStateHandle only for small UI state parameters, not business data.
Advanced: How to Debug What is Saving Too Much State
Use the following:
1. Enable StrictMode
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectActivityLeaks()
.penaltyLog()
.build()
)
2. Use Android Studio State Inspector (API 34+)
Helps detect Fragment and ViewModel saved state bloat.
3. Add Logging in onSaveInstanceState()
override fun onSaveInstanceState(outState: Bundle) {
Log.d("STATE_SIZE", outState.keySet().joinToString())
super.onSaveInstanceState(outState)
}
4. ADB profile binder transactions
adb shell dumpsys activity processes
Framework Examples
Below are common cases in cross-platform mobile frameworks.
Android + Capacitor / Ionic
Angular/React state objects inside WebView can get serialized accidentally if:
- You store huge JS objects in
localStorage - A plugin tries to sync state via Bundle
- The WebView restores its own state
Fix
Disable WebView state restoration:
webView.saveState = false
webView.restoreState = false
Or ensure your app clears JS state before backgrounding.
React Native
Avoid passing large JSON props from native to JS, especially via Intent.
Flutter
Large navigation arguments or widget trees with state restoration enabled may cause similar issues.
Best Practices to Prevent TransactionTooLargeException
✔ Keep onSaveInstanceState() minimal
Only store primitive UI values.
✔ Never pass lists or large JSON blobs in Bundles
✔ Avoid Serializable for large complex models
✔ Store big data in local DB (Room) or disk cache
✔ Use shared ViewModels instead of passing data
✔ Disable Fragment state saving if not needed
✔ Don’t register ActivityResultLaunchers in loops
✔ Keep navigation arguments small
Conclusion
TransactionTooLargeException is a classic Android pitfall that usually appears when too much data is being saved in Activity or Fragment state bundles. By keeping state lightweight, moving large data into repositories, and avoiding heavy Parcelable/Intent usage, you can ensure your application remains stable across rotations, background transitions, and activity lifecycle events.

