eclipse-vertx/vert.x · error · DecodeException

Unexpected trailing token

Error message

Unexpected trailing token

What it means

After parsing the requested JSON value, JacksonCodec checks that the parser has been fully consumed (no remaining token). If extra content follows the first complete JSON value, it throws DecodeException("Unexpected trailing token"). This enforces that the input is exactly one JSON document.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/json/jackson/JacksonCodec.java:280

  public Object fromBuffer(Buffer buf) throws DecodeException {
    return fromParser(createParser(buf), Object.class);
  }

  public static <T> T fromParser(JsonParser parser, Class<T> type) throws DecodeException {
    Object res;
    JsonToken remaining;
    try {
      parser.nextToken();
      res = parseValue(parser);
      remaining = parser.nextToken();
    } catch (IOException e) {
      throw new DecodeException(e.getMessage(), e);
    } finally {
      close(parser);
    }
    if (remaining != null) {
      throw new DecodeException("Unexpected trailing token");
    }
    return cast(res, type);
  }

  /**
   * Parse a JSON value given the {@code parser}, consuming the current parser token and possibly more
   * when parsing an object or an array.
   *
   * @param parser the parser
   * @return the parsed value as an object
   */
  public static Object parseValue(JsonParser parser) throws IOException, DecodeException {
    switch (parser.currentTokenId()) {
      case JsonTokenId.ID_START_OBJECT:
        return internalParseObject(parser);
      case JsonTokenId.ID_START_ARRAY:
        return internalParseArray(parser);
      case JsonTokenId.ID_STRING:

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Remove or split the trailing data — parse each JSON document separately (split on newline for NDJSON)
  2. Validate the payload contains exactly one JSON document before decoding
  3. If multiple documents are expected, parse them individually in a loop with a streaming parser
  4. Trim whitespace/BOM; if the extra token is unexpected, log the raw tail and fix the producer

Example fix

// before
Object o = Json.decodeValue(ndjsonBuffer); // '{...}\n{...}' throws
// after
for (String line : ndjsonBuffer.toString().split("\n")) {
  if (line.isBlank()) continue;
  Object o = Json.decodeValue(line);
  handle(o);
}
Defensive patterns

Strategy: validation

Validate before calling

// Java
// Ensure exactly one JSON document per decode unit
public static List<String> splitJsonDocuments(String payload) {
  return java.util.Arrays.stream(payload.split("\n"))
      .map(String::strip)
      .filter(s -> !s.isEmpty())
      .toList();
}

Type guard

public static boolean isSingleJsonDocument(String s) {
  if (s == null) return false;
  String t = s.strip();
  if (t.isEmpty()) return false;
  try (com.fasterxml.jackson.core.JsonParser p = JacksonCodec.createParser(t)) {
    while (p.nextToken() != null) { /* consume */ }
    return true;
  } catch (Exception e) { return false; }
}

Try / catch

try {
  return Json.decodeValue(buffer);
} catch (DecodeException e) {
  if (e.getMessage().contains("Unexpected trailing token")) {
    // input has multiple documents: split and decode each
    return splitJsonDocuments(buffer.toString()).stream()
        .map(Json::decodeValue).toList();
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling fromString/fromBuffer/fromStream/fromReader with input that contains a valid JSON value followed by extra data — e.g. 'null null', '{...} garbage', NDJSON/multiple concatenated JSON documents, or an HTTP body with appended bytes.

Common situations: Decoding newline-delimited JSON (NDJSON) streams a document at a time but passing the whole payload; concatenating JSON responses without an array wrapper; binary padding or a stray BOM/whitespace artifact after the JSON; proxy pipelines that append data.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/35024eaf23b8e0d7. Report an issue: GitHub.