{"record":{"id":"7bbfbf5f6d4f9cbb","repo":"google/gson","slug":"nesting-limit-reached","errorCode":null,"errorMessage":"Nesting limit {} reached{}","messagePattern":"Nesting limit (.+?) reached(.+?)","errorType":"exception","errorClass":"MalformedJsonException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/stream/JsonReader.java","lineNumber":1495,"sourceCode":"          pos += peekedNumberLength;\n          break;\n        case PEEKED_EOF:\n          // Do nothing\n          return;\n        default:\n          // For all other tokens there is nothing to do; token has already been consumed from\n          // underlying reader\n      }\n      peeked = PEEKED_NONE;\n    } while (count > 0);\n\n    pathIndices[stackSize - 1]++;\n  }\n\n  private void push(int newTop) throws MalformedJsonException {\n    // - 1 because stack contains as first element either EMPTY_DOCUMENT or NONEMPTY_DOCUMENT\n    if (stackSize - 1 >= nestingLimit) {\n      throw new MalformedJsonException(\n          \"Nesting limit \" + nestingLimit + \" reached\" + locationString());\n    }\n\n    if (stackSize == stack.length) {\n      int newLength = stackSize * 2;\n      stack = Arrays.copyOf(stack, newLength);\n      pathIndices = Arrays.copyOf(pathIndices, newLength);\n      pathNames = Arrays.copyOf(pathNames, newLength);\n    }\n    stack[stackSize++] = newTop;\n  }\n\n  /**\n   * Returns true once {@code limit - pos >= minimum}. If the data is exhausted before that many\n   * characters are available, this returns false.\n   */\n  private boolean fillBuffer(int minimum) throws IOException {\n    char[] buffer = this.buffer;","sourceCodeStart":1477,"sourceCodeEnd":1513,"githubUrl":"https://github.com/google/gson/blob/310ac341f2f92a454b229bf21f70d2d18b2b6db7/gson/src/main/java/com/google/gson/stream/JsonReader.java#L1477-L1513","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nJsonReader r = new JsonReader(reader);\nr.setNestingLimit(2);\nr.beginArray(); // fails on [{\"a\":[true]}]\n\n// after\nJsonReader r = new JsonReader(reader);\nr.setNestingLimit(255);\nr.beginArray();","handlingStrategy":"validation","validationCode":"int maxExpected = 64; // tune to your schema\nreader.setNestingLimit(maxExpected);\ntry {\n  reader.beginArray();\n  ...\n} catch (MalformedJsonException e) {\n  // map to a 400 / domain error\n}","typeGuard":"static boolean withinExpectedDepth(int current, int limit) {\n  return current <= limit;\n}","tryCatchPattern":"try {\n  parse(reader);\n} catch (MalformedJsonException e) {\n  if (e.getMessage().contains(\"Nesting limit\")) return Result.tooDeep();\n  throw e;\n}","preventionTips":["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."],"tags":["java","gson","jsonreader","security","nesting"],"backgroundTag":null,"analyzedSha":"310ac341f2f92a454b229bf21f70d2d18b2b6db7","analyzedAt":"2026-08-10T02:58:47.455Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}