{"id":"87bc57b1353e59e9","repo":"google/gson","slug":"nesting-limit-nestinglimit-reached-loca","errorCode":null,"errorMessage":"Nesting limit \" + nestingLimit + \" reached\" + locationString()","messagePattern":"Nesting limit \" \\+ nestingLimit \\+ \" reached\" \\+ locationString\\(\\)","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/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/stream/JsonReader.java#L1477-L1513","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nreader.setNestingLimit(2);\nreader.beginArray(); reader.beginArray(); reader.beginArray(); // throws on 3rd\n\n// after\nreader.setNestingLimit(JsonReader.DEFAULT_NESTING_LIMIT); // 255\n// or a value sized to your real data, e.g. 64","handlingStrategy":"validation","validationCode":"// Choose a nesting limit sized to your data; default is 255\nint maxExpectedDepth = 64;\nreader.setNestingLimit(Math.max(maxExpectedDepth, JsonReader.DEFAULT_NESTING_LIMIT));\n// For untrusted input, set a firm cap and catch MalformedJsonException\nreader.setNestingLimit(64);","typeGuard":null,"tryCatchPattern":"try {\n  reader.beginObject();\n} catch (MalformedJsonException e) {\n  if (e.getMessage().startsWith(\"Nesting limit\")) {\n    // report oversized nesting; do not retry with a higher limit blindly\n  } else throw e;\n}","preventionTips":["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."],"tags":["gson","jsonreader","nesting-limit","security","dos-protection"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}