airbnb/lottie-android · error · JsonDataException
Nesting too deep at {}
Error message
Nesting too deep at {} What it means
JsonReader.pushScope() manages the parser's scope stack. The stack starts at 32 entries and doubles on demand, but when it reaches 256 levels deep it throws JsonDataException('Nesting too deep'). This is a hard cap to prevent stack-overflow-style attacks or pathological input. Lottie animations should never approach this depth under normal conditions.
Source
Thrown at lottie/src/main/java/com/airbnb/lottie/parser/moshi/JsonReader.java:237
/**
* Returns a new instance that reads UTF-8 encoded JSON from {@code source}.
*/
public static JsonReader of(BufferedSource source) {
return new JsonUtf8Reader(source);
}
// Package-private to control subclasses.
JsonReader() {
scopes = new int[32];
pathNames = new String[32];
pathIndices = new int[32];
}
final void pushScope(int newTop) {
if (stackSize == scopes.length) {
if (stackSize == 256) {
throw new JsonDataException("Nesting too deep at " + getPath());
}
scopes = Arrays.copyOf(scopes, scopes.length * 2);
pathNames = Arrays.copyOf(pathNames, pathNames.length * 2);
pathIndices = Arrays.copyOf(pathIndices, pathIndices.length * 2);
}
scopes[stackSize++] = newTop;
}
/**
* Throws a new IO exception with the given message and a context snippet
* with this reader's content.
*/
final JsonEncodingException syntaxError(String message) throws JsonEncodingException {
throw new JsonEncodingException(message + " at path " + getPath());
}
/**View on GitHub (pinned to 05ea92e903)
Solutions
- Verify the Lottie JSON is well-formed and not excessively nested using a standard JSON parser or validator.
- If accepting animations from untrusted sources, pre-validate nesting depth before passing to LottieAnimationView/LottieComposition.
- Re-download or re-export the animation to eliminate corruption.
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check nesting depth before passing to Lottie
public static boolean isNestingSafe(JsonElement json, int maxDepth) {
if (maxDepth <= 0) return false;
if (json.isJsonObject()) {
for (Map.Entry<String, JsonElement> e : json.getAsJsonObject().entrySet()) {
if (!isNestingSafe(e.getValue(), maxDepth - 1)) return false;
}
} else if (json.isJsonArray()) {
for (JsonElement e : json.getAsJsonArray()) {
if (!isNestingSafe(e, maxDepth - 1)) return false;
}
}
return true;
} Try / catch
try {
LottieCompositionFactory.fromAsset(context, name);
} catch (JsonDataException e) {
// nesting too deep — reject untrusted input
} Prevention
- Never load untrusted Lottie JSON without pre-validation.
- If accepting animations from users/network, pre-parse with Gson/Jackson to check nesting depth.
- Treat excessively nested JSON as a potential attack indicator.
When it happens
Trigger: Loading a JSON stream (Lottie animation or otherwise) with more than 256 levels of nested arrays/objects. This can be caused by a maliciously crafted file (JSON nesting bomb), a severely corrupted file, or a programming error producing deeply recursive JSON.
Common situations: Security: untrusted JSON input designed to exhaust memory; corrupted Lottie file with deeply nested (possibly circular-referenced) structures; accidental double-wrapping of JSON payloads by a broken server or CDN.
Related errors
- Expected BEGIN_ARRAY but was {} at path {}
- Expected END_ARRAY but was {} at path {}
- Expected BEGIN_OBJECT but was {} at path {}
- Expected END_OBJECT but was {} at path {}
- Expected a name but was {} at path {}
AI-assisted analysis of airbnb/lottie-android@05ea92e903 (2026-08-14).
Data as JSON: /api/errors/0aca14a97c79b6b8.
Report an issue: GitHub.