google/gson · error · JsonSyntaxException

JSON document was not fully consumed.

Error message

JSON document was not fully consumed.

What it means

Thrown by assertFullConsumption (called from Gson.fromJson(Reader, TypeToken)) when, after successfully reading one JSON value, the reader still has more tokens (peek() != END_DOCUMENT). The Reader/TypeToken overload enforces single-value documents to catch trailing garbage; multiple top-level values or trailing whitespace-with-data are rejected. It is a JsonSyntaxException (a RuntimeException).

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 8b8628c656)

Solutions

  1. Use the JsonReader-based overload gson.fromJson(JsonReader, TypeToken) which does NOT enforce full consumption and lets you loop over multiple top-level values.
  2. Strip trailing data or split the input into single JSON values before parsing.
  3. For NDJSON, read line-by-line and parse each line separately.
  4. Validate that the input contains exactly one top-level JSON value before calling the Reader overload.

Example fix

// before: two values in one Reader
String two = "{\"a\":1}{\"b\":2}";
Foo f = gson.fromJson(new StringReader(two), TypeToken.get(Foo.class)); // throws

// after: use JsonReader to consume multiple values
try (JsonReader r = new JsonReader(new StringReader(two))) {
  while (r.peek() != JsonToken.END_DOCUMENT) {
    Foo f = gson.fromJson(r, TypeToken.get(Foo.class));
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate single top-level value before the Reader overload
static boolean hasSingleTopLevel(String json) {
  JsonReader r = new JsonReader(new StringReader(json));
  try {
    r.skipValue();
    return r.peek() == JsonToken.END_DOCUMENT;
  } catch (IOException e) { return false; }
}

Type guard

static boolean isSingleValueDocument(Reader reader) {
  JsonReader r = new JsonReader(reader);
  try { r.skipValue(); return r.peek() == JsonToken.END_DOCUMENT; }
  catch (IOException e) { return false; }
}

Try / catch

try {
  Foo f = gson.fromJson(reader, TypeToken.get(Foo.class));
} catch (JsonSyntaxException e) {
  if (e.getMessage().contains("not fully consumed")) {
    // switch to JsonReader-based loop for multi-value streams
  } else throw e;
}

Prevention

When it happens

Trigger: Feeding gson.fromJson(reader, TypeToken.get(Foo.class)) a stream containing two concatenated JSON objects {"a":1}{"b":2}; a value followed by trailing non-whitespace; an array where a single object was expected, or vice versa, leaving remainder; NDJSON/JSON Lines fed to a single-value parser.

Common situations: Concatenated responses from a server; NDJSON log files; buffered streams that include the next message; copy-paste of multiple JSON snippets into one input; incorrect framing of a network protocol.

Related errors


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