openzipkin/zipkin · error · IllegalArgumentException
Not a valid JSON object, start token: %s
Error message
Not a valid JSON object, start token: %s
What it means
JsonSerializers.parseSpan requires the parser to start at a JSON object ({...}) before reading span fields; anything else (array, string, null token from empty input) fails immediately with IllegalArgumentException naming the offending start token. This parser decodes span documents returned from Elasticsearch, so the error means the storage returned a span-shaped position that is not a JSON object.
Source
Thrown at zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java:44
public static final JsonFactory JSON_FACTORY = new JsonFactory();
public static JsonGenerator jsonGenerator(OutputStream stream) {
try {
return JSON_FACTORY.createGenerator(stream);
} catch (IOException e) {
throw new AssertionError("Could not create JSON generator for a memory stream.", e);
}
}
public interface ObjectParser<T> {
T parse(JsonParser jsonParser) throws IOException;
}
public static final ObjectParser<Span> SPAN_PARSER = JsonSerializers::parseSpan;
static Span parseSpan(JsonParser parser) throws IOException {
if (!parser.isExpectedStartObjectToken()) {
throw new IllegalArgumentException("Not a valid JSON object, start token: " +
parser.currentToken());
}
Span.Builder result = Span.newBuilder();
JsonToken value;
while ((value = parser.nextValue()) != JsonToken.END_OBJECT) {
if (value == null) {
throw new IOException("End of input while parsing object.");
}
if (value == JsonToken.VALUE_NULL) {
continue;
}
switch (parser.currentName()) {
case "traceId":
result.traceId(parser.getText());
break;
case "parentId":View on GitHub (pinned to 878ce2a1fa)
Solutions
- Inspect the JSON you feed/expect: each span must be a single object starting with '{'.
- If data comes from an index, reindex or delete the malformed documents (query by _source shape to find them).
- In tests/tools, wrap the parser on the correct node (the object inside hits[]._source), not the outer response.
- Align zipkin versions so converters and parsers agree on response structure.
Example fix
// before
JsonParser p = factory.createParser("[{\"traceId\":\"...\"}]"); // array
SPAN_PARSER.parse(p); // Not a valid JSON object, start token: START_ARRAY
// after
JsonParser p = factory.createParser("{\"traceId\":\"...\",\"id\":\"...\"}");
Span span = SPAN_PARSER.parse(p); Defensive patterns
Strategy: type-guard
Validate before calling
// validate shape before parsing if input provenance is unknown
var node = objectMapper.readTree(spanJson);
if (!node.isObject()) {
throw new IOException("Span payload must be a JSON object, was: " + node.getNodeType());
} Type guard
boolean isSpanObjectShape(com.fasterxml.jackson.databind.JsonNode n) {
return n.isObject() && n.has("traceId") && n.has("id");
} Try / catch
try {
Span span = JsonSerializers.SPAN_PARSER.parse(parser);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Not a valid JSON object")) {
// skip/reject the malformed record, log the raw payload
}
} Prevention
- Always anchor the parser on the span object node (hits[]._source), not the outer response.
- Validate externally sourced span JSON is an object with traceId/id before parsing.
- Write spans into ES only through Zipkin's own sender/collector so shapes are guaranteed.
When it happens
Trigger: Search results whose hits or source values are not objects: a malformed index containing non-object documents, a converter feeding the parser at the wrong depth, or manually crafted/consumed JSON tests that pass arrays where span objects are expected.
Common situations: Direct use of JsonSerializers.SPAN_PARSER in tooling/tests; corrupted index data; response-shape mismatch after cluster upgrade; feeding concatenated JSON streams.
Related errors
- End of input while parsing object.
- Invalid span, expecting annotations array start, got: {}
- Invalid span, expecting tags object, got: {}
- Not a valid JSON object, start token: {}
- Incomplete annotation at {}
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/f5034fa7aafd94d6.
Report an issue: GitHub.