google/gson · error · MalformedJsonException
Nesting limit {} reached{}
Error message
Nesting limit {} reached{} What it means
Thrown by JsonReader.push() (JsonReader.java:1492-1497) when opening a new array or object would exceed the configured nesting limit (default 255). The guard stackSize - 1 >= nestingLimit fires inside beginArray/beginObject (and during skipValue) to stop unbounded recursion, protecting recursive TypeAdapter implementations from StackOverflowError. It is a MalformedJsonException carrying locationString() for context.
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 310ac341f2)
Solutions
- Raise the limit with setNestingLimit to match the maximum expected depth.
- If the depth is unexpected, validate/reject the payload upstream rather than relying on the parser.
- For untrusted input, keep a deliberately low limit and treat MalformedJsonException as a 400/rejection.
- Inspect locationString() in the exception to find the offending nesting level.
Example fix
// before
JsonReader r = new JsonReader(reader);
r.setNestingLimit(2);
r.beginArray(); // fails on [{"a":[true]}]
// after
JsonReader r = new JsonReader(reader);
r.setNestingLimit(255);
r.beginArray(); Defensive patterns
Strategy: validation
Validate before calling
int maxExpected = 64; // tune to your schema
reader.setNestingLimit(maxExpected);
try {
reader.beginArray();
...
} catch (MalformedJsonException e) {
// map to a 400 / domain error
} Type guard
static boolean withinExpectedDepth(int current, int limit) {
return current <= limit;
} Try / catch
try {
parse(reader);
} catch (MalformedJsonException e) {
if (e.getMessage().contains("Nesting limit")) return Result.tooDeep();
throw e;
} Prevention
- Set an explicit nesting limit matched to your schema for untrusted input.
- Treat 'Nesting limit reached' as a security signal, not a recoverable parse error.
- Inspect locationString() to learn the actual depth of offending payloads.
When it happens
Trigger: Parsing deeply nested JSON such as [[[[...]]]] beyond the limit; a malicious or buggy payload designed to exhaust the stack; a low nesting limit set via setNestingLimit combined with legitimately nested data; recursive adapters that delegate through many levels.
Common situations: Security-sensitive endpoints parsing untrusted JSON (raise or lower the limit accordingly); tightening the limit for a known-shallow schema and then receiving deeper data; third-party feeds with arbitrary nesting; regression after raising depth expectations.
Related errors
- Invalid nesting limit: {}
- JsonReader is closed
- Expected a long but was {}{}
- Expected an int but was {}{}
- End of input{}
AI-assisted analysis of google/gson@310ac341f2 (2026-08-10).
Data as JSON: /api/errors/7bbfbf5f6d4f9cbb.
Report an issue: GitHub.