google/gson · error · MalformedJsonException
Nesting limit " + nestingLimit + " reached" + locationString
Error message
Nesting limit " + nestingLimit + " reached" + locationString()
What it means
Thrown by JsonReader.push() (as MalformedJsonException) when opening a new array or object would exceed the configured nesting limit (setNestingLimit, default 255). The check `stackSize - 1 >= nestingLimit` guards against deeply nested input that could cause a StackOverflowError in recursive TypeAdapter implementations.
Source
Thrown at gson/src/main/java/com/google/gson/stream/JsonReader.java:1495
pos += peekedNumberLength;
break;
case PEEKED_EOF:
// Do nothing
return;
default:
// For all other tokens there is nothing to do; token has already been consumed from
// underlying reader
}
peeked = PEEKED_NONE;
} while (count > 0);
pathIndices[stackSize - 1]++;
}
private void push(int newTop) throws MalformedJsonException {
// - 1 because stack contains as first element either EMPTY_DOCUMENT or NONEMPTY_DOCUMENT
if (stackSize - 1 >= nestingLimit) {
throw new MalformedJsonException(
"Nesting limit " + nestingLimit + " reached" + locationString());
}
if (stackSize == stack.length) {
int newLength = stackSize * 2;
stack = Arrays.copyOf(stack, newLength);
pathIndices = Arrays.copyOf(pathIndices, newLength);
pathNames = Arrays.copyOf(pathNames, newLength);
}
stack[stackSize++] = newTop;
}
/**
* Returns true once {@code limit - pos >= minimum}. If the data is exhausted before that many
* characters are available, this returns false.
*/
private boolean fillBuffer(int minimum) throws IOException {
char[] buffer = this.buffer;View on GitHub (pinned to 8b8628c656)
Solutions
- Raise the limit with setNestingLimit() to accommodate legitimate maximum depth.
- Keep the default (255) unless you have a specific reason to lower it.
- Pre-validate or sanitize untrusted input; reject payloads above a sane depth before parsing.
- Make recursive TypeAdapters iterative to reduce per-level stack usage.
Example fix
// before reader.setNestingLimit(2); reader.beginArray(); reader.beginArray(); reader.beginArray(); // throws on 3rd // after reader.setNestingLimit(JsonReader.DEFAULT_NESTING_LIMIT); // 255 // or a value sized to your real data, e.g. 64
Defensive patterns
Strategy: validation
Validate before calling
// Choose a nesting limit sized to your data; default is 255 int maxExpectedDepth = 64; reader.setNestingLimit(Math.max(maxExpectedDepth, JsonReader.DEFAULT_NESTING_LIMIT)); // For untrusted input, set a firm cap and catch MalformedJsonException reader.setNestingLimit(64);
Try / catch
try {
reader.beginObject();
} catch (MalformedJsonException e) {
if (e.getMessage().startsWith("Nesting limit")) {
// report oversized nesting; do not retry with a higher limit blindly
} else throw e;
} Prevention
- Keep the default nesting limit (255) unless you have a concrete reason to change it.
- For untrusted JSON, set an explicit cap matching your legitimate maximum depth.
- Reject payloads exceeding a sane depth before parsing when feasible.
- Prefer iterative over recursive TypeAdapters to keep per-level stack usage low.
When it happens
Trigger: Parsing JSON with nesting depth greater than the limit; e.g. setNestingLimit(2) and reading [[[true]]]. Also triggered by maliciously crafted 'JSON bomb' payloads designed to exhaust the stack.
Common situations: Lowering the nesting limit for safety and then hitting legitimate deeply-nested data; receiving untrusted JSON (web API, file upload) where an attacker may nest thousands of levels; recursive data structures serialized to JSON.
Related errors
- ReflectionAccessFilter does not permit using reflection for
- Attempted to deserialize a java.lang.Class. Forgot to regist
- Failed parsing '" + s + "' as InetAddress; at path " + in.ge
- Invalid nesting limit: " + limit
- JsonReader is closed
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/87bc57b1353e59e9.json.
Report an issue: GitHub.