{"id":"6a67d06d653c2709","repo":"google/gson","slug":"failed-parsing-json-source-to-json","errorCode":null,"errorMessage":"Failed parsing JSON source to Json","messagePattern":"Failed parsing JSON source to Json","errorType":"exception","errorClass":"JsonParseException","httpStatus":null,"severity":"critical","filePath":"gson/src/main/java/com/google/gson/JsonStreamParser.java","lineNumber":91,"sourceCode":"  /**\n   * Returns the next available {@link JsonElement} on the reader. Throws a {@link\n   * NoSuchElementException} if no element is available.\n   *\n   * @return the next available {@code JsonElement} on the reader.\n   * @throws JsonParseException if the incoming stream is malformed JSON.\n   * @throws NoSuchElementException if no {@code JsonElement} is available.\n   * @since 1.4\n   */\n  @Override\n  public JsonElement next() throws JsonParseException {\n    if (!hasNext()) {\n      throw new NoSuchElementException();\n    }\n\n    try {\n      return Streams.parse(parser);\n    } catch (StackOverflowError | OutOfMemoryError e) {\n      throw new JsonParseException(\"Failed parsing JSON source to Json\", e);\n    }\n  }\n\n  /**\n   * Returns true if a {@link JsonElement} is available on the input for consumption\n   *\n   * @return true if a {@link JsonElement} is available on the input, false otherwise\n   * @throws JsonParseException if the incoming stream is malformed JSON.\n   * @since 1.4\n   */\n  @Override\n  public boolean hasNext() {\n    synchronized (lock) {\n      try {\n        return parser.peek() != JsonToken.END_DOCUMENT;\n      } catch (MalformedJsonException e) {\n        throw new JsonSyntaxException(e);\n      } catch (IOException e) {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/JsonStreamParser.java#L73-L109","documentation":"JsonStreamParser.next() delegates to Streams.parse and catches StackOverflowError/OutOfMemoryError, rethrowing as JsonParseException. It is the streaming counterpart of error 42: the next value in a concatenated stream is too large or too deeply nested for the JVM.","triggerScenarios":"Iterating a JsonStreamParser over a stream where one element is pathologically nested or huge; processing NDJSON records where a single record overflows memory.","commonSituations":"Log/event ingestion pipelines; NDJSON consumers; adversarial input in a streaming endpoint.","solutions":["Increase -Xss/-Xmx for legitimate workloads.","Enforce per-record size and depth caps before parsing.","Use a bounded JsonReader pass and skip/abort oversized records.","Switch from tree-based Streams.parse to direct token streaming for memory control."],"exampleFix":"// before\nwhile (parser.hasNext()) {\n  JsonElement e = parser.next();\n}\n\n// after (bounded reader per record)\ntry (JsonReader r = new JsonReader(reader)) {\n  r.setStrictness(Strictness.STRICT);\n  // walk tokens, enforce MAX_DEPTH and MAX_BYTES\n}","handlingStrategy":"validation","validationCode":"// enforce per-record size before adding to stream\nif (recordBytes > MAX_RECORD_BYTES) skip();\n","typeGuard":null,"tryCatchPattern":"try {\n  JsonElement e = parser.next();\n} catch (JsonParseException ex) {\n  if (ex.getCause() instanceof StackOverflowError\n      || ex.getCause() instanceof OutOfMemoryError) {\n    // log and skip oversized record rather than abort stream\n  } else throw ex;\n}\n","preventionTips":["Bound per-record size and depth.","Prefer token-level JsonReader streaming for untrusted input.","Tune -Xss/-Xmx for record peak sizes."],"tags":["parsing","streaming","resource-exhaustion","stack-overflow","oom"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}