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

  1. Raise the limit with setNestingLimit() to accommodate legitimate maximum depth.
  2. Keep the default (255) unless you have a specific reason to lower it.
  3. Pre-validate or sanitize untrusted input; reject payloads above a sane depth before parsing.
  4. 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

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


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/87bc57b1353e59e9.json. Report an issue: GitHub.