google/gson · error · JsonSyntaxException

JSON document was not fully consumed.

Error message

JSON document was not fully consumed.

What it means

Thrown by Gson.assertFullConsumption when, after successfully reading a value, the reader has not reached END_DOCUMENT - meaning there is trailing non-whitespace content after the top-level JSON value. It is raised as a JsonSyntaxException because a valid JSON document must consist of exactly one top-level value. This catches concatenated/malformed input early.

Solutions

  1. Feed only a single JSON document to fromJson; if you have multiple, parse them individually (e.g. line by line for NDJSON).
  2. Trim and inspect the input string for trailing non-JSON characters before parsing.
  3. Use a JsonReader in a loop with hasNext-style handling when multiple top-level values are expected.
  4. If lenient trailing content is intentional and acceptable, strip it before calling fromJson.

Example fix

// before
gson.fromJson("{}{}", Map.class); // trailing object -> throws

// after
String[] docs = input.split("\n");
for (String d : docs) gson.fromJson(d, Map.class);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a single top-level JSON value before parsing
String trimmed = json.strip();
JsonReader r = new JsonReader(new StringReader(trimmed));
r.setStrictness(Strictness.STRICT);
// parse once; assertFullConsumption-style check
Object v = gson.getAdapter(Object.class).read(r);
if (r.peek() != JsonToken.END_DOCUMENT) {
  throw new IllegalStateException("Trailing content after JSON document");
}

Try / catch

try { gson.fromJson(json, type); }
catch (JsonSyntaxException e) {
  if (e.getMessage().contains("not fully consumed")) {
    // split NDJSON or strip trailing content, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Parsing a string that contains two JSON objects back-to-back (e.g. "{}{}"); trailing garbage after the JSON value (a stray comma, semicolon, or text); reading from a stream that appended log lines; lenient concatenation of multiple documents into one input.

Common situations: NDJSON/multi-document content accidentally fed to a single-document parser; server response with trailing debug text; buffered reader reused with leftover content; copy-paste artifacts after the closing brace.

Related errors


AI-assisted analysis of google/gson@310ac341f2 (2026-08-10). Data as JSON: /api/errors/1b059d4232aeda78. Report an issue: GitHub.

Appendix: source

Thrown at gson/src/main/java/com/google/gson/Gson.java:1222

   *
   * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null}
   *     or if {@code json} is empty.
   * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
   * @see #fromJson(Reader, TypeToken)
   * @see #fromJson(JsonElement, Class)
   * @since 2.10
   */
  public <T> T fromJson(JsonElement json, TypeToken<T> typeOfT) throws JsonSyntaxException {
    if (json == null) {
      return null;
    }
    return fromJson(new JsonTreeReader(json), typeOfT);
  }

  private static void assertFullConsumption(Object obj, JsonReader reader) {
    try {
      if (obj != null && reader.peek() != JsonToken.END_DOCUMENT) {
        throw new JsonSyntaxException("JSON document was not fully consumed.");
      }
    } catch (MalformedJsonException e) {
      throw new JsonSyntaxException(e);
    } catch (IOException e) {
      throw new JsonIOException(e);
    }
  }

  /**
   * Proxy type adapter for cyclic type graphs.
   *
   * <p><b>Important:</b> Setting the delegate adapter is not thread-safe; instances of {@code
   * FutureTypeAdapter} must only be published to other threads after the delegate has been set.
   *
   * @see Gson#threadLocalAdapterResults
   */
  static class FutureTypeAdapter<T> extends SerializationDelegatingTypeAdapter<T> {
    private TypeAdapter<T> delegate = null;

View on GitHub (pinned to 310ac341f2)