google/gson · error · EOFException

End of input{}

Error message

End of input{}

What it means

Thrown by JsonReader.nextNonWhitespace(true) as an EOFException (JsonReader.java:1628-1629) when the reader needs another non-whitespace character but fillBuffer returns false because the underlying stream is exhausted. The throwOnEof=true call sites are the structural readers (begin/end, doPeek value discovery) that require a token; reaching EOF mid-structure means the JSON is truncated or incomplete.

Source

Thrown at gson/src/main/java/com/google/gson/stream/JsonReader.java:1629

        }
      } else if (c == '#') {
        pos = p;
        /*
         * Skip a # hash end-of-line comment. The JSON RFC doesn't
         * specify this behavior, but it's required to parse
         * existing documents. See http://b/2571423.
         */
        checkLenient();
        skipToEndOfLine();
        p = pos;
        l = limit;
      } else {
        pos = p;
        return c;
      }
    }
    if (throwOnEof) {
      throw new EOFException("End of input" + locationString());
    } else {
      return -1;
    }
  }

  private void checkLenient() throws MalformedJsonException {
    if (strictness != Strictness.LENIENT) {
      throw syntaxError(
          "Use JsonReader.setStrictness(Strictness.LENIENT) to accept malformed JSON");
    }
  }

  /**
   * Advances the position until after the next newline character. If the line is terminated by
   * "\r\n", the '\n' must be consumed as whitespace by the caller.
   */
  private void skipToEndOfLine() throws IOException {
    while (pos < limit || fillBuffer(1)) {

View on GitHub (pinned to 310ac341f2)

Solutions

  1. Check peek()==JsonToken.END_DOCUMENT before consuming tokens.
  2. Use hasNext() in loops instead of fixed counts.
  3. Validate the source is complete (Content-Length, checksum) before parsing.
  4. Catch EOFException at the parse boundary and map it to a domain error (e.g. 'incomplete payload').

Example fix

// before
reader.beginObject();
String n = reader.nextName(); // throws EOFException on empty input

// after
if (reader.peek() == JsonToken.END_DOCUMENT) {
  return null;
}
reader.beginObject();
Defensive patterns

Strategy: try-catch

Validate before calling

if (reader.peek() == JsonToken.END_DOCUMENT) {
  return Optional.empty();
}
reader.beginObject();
...

Type guard

static boolean hasMore(JsonReader r) throws IOException {
  return r.peek() != JsonToken.END_DOCUMENT;
}

Try / catch

try {
  reader.beginObject();
} catch (EOFException e) {
  return null; // or a domain 'empty input' result
}

Prevention

When it happens

Trigger: Calling beginObject/beginArray/nextName/etc. when the stream ends prematurely (e.g. JSON cut off mid-object, an empty or blank document, a network read truncated). Also when hasNext is not used and the loop assumes more tokens exist.

Common situations: Truncated HTTP responses; streaming over sockets that close early; empty input passed to a parser expecting an object; partial writes from a producer; forgetting to handle the END_DOCUMENT token from peek().

Related errors


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