openzipkin/zipkin · error · IOException
Invalid span, expecting tags object, got: {}
Error message
Invalid span, expecting tags object, got: {} What it means
In parseSpan, the 'tags' field must be a JSON object (START_OBJECT); any other shape (array, string, number) throws IOException('Invalid span, expecting tags object, got: <token>'). Tags are key/value pairs, and the parser then reads each entry with parser.nextValue() until END_OBJECT.
Source
Thrown at zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java:98
case "localEndpoint":
result.localEndpoint(parseEndpoint(parser));
break;
case "remoteEndpoint":
result.remoteEndpoint(parseEndpoint(parser));
break;
case "annotations":
if (value != JsonToken.START_ARRAY) {
throw new IOException("Invalid span, expecting annotations array start, got: " +
value);
}
while (parser.nextToken() != JsonToken.END_ARRAY) {
Annotation a = parseAnnotation(parser);
result.addAnnotation(a.timestamp(), a.value());
}
break;
case "tags":
if (value != JsonToken.START_OBJECT) {
throw new IOException("Invalid span, expecting tags object, got: " + value);
}
while (parser.nextValue() != JsonToken.END_OBJECT) {
result.putTag(parser.currentName(), parser.getValueAsString());
}
break;
case "debug":
result.debug(parser.getBooleanValue());
break;
case "shared":
result.shared(parser.getBooleanValue());
break;
default:
// Skip
}
}
return result.build();
}View on GitHub (pinned to 878ce2a1fa)
Solutions
- Fix the document: tags must be an object, e.g. "tags":{"http.path":"/api"}.
- Fix the producing serializer (custom collector/ETL) to emit tags as a JSON map.
- Reindex or delete malformed documents in the affected indices.
- Build spans via Span.Builder.putTag in your own code so the encoding is always correct.
Example fix
// before
{"traceId":"abc","id":"def","tags":[{"key":"http.path","value":"/api"}]}
// -> IOException: Invalid span, expecting tags object, got: START_ARRAY
// after
{"traceId":"abc","id":"def","tags":{"http.path":"/api"}} Defensive patterns
Strategy: type-guard
Validate before calling
var span = objectMapper.readTree(spanJson);
if (span.has("tags") && !span.get("tags").isObject()) {
throw new IOException("'tags' must be a JSON object of name/value pairs");
} Type guard
boolean tagsWellFormed(JsonNode span) {
JsonNode t = span.get("tags");
return t == null || t.isObject();
} Try / catch
try { Span s = SPAN_PARSER.parse(p); }
catch (IOException e) {
if (e.getMessage().startsWith("Invalid span, expecting tags object")) {
// reject the document; fix the producer emitting tags as arrays/scalars
}
} Prevention
- Emit tags as a JSON map {"key":"value"}.
- Use Span.Builder.putTag in producers instead of hand-writing tag JSON.
- Validate converted payloads from other trace formats before indexing them.
When it happens
Trigger: A span document with "tags":["http.path"] or "tags":"none" — tags encoded as an array or scalar instead of an object map — being parsed by SPAN_PARSER.
Common situations: Custom ingest pipelines or fixtures encoding tags differently; converting from other trace formats (some use arrays of {k,v}); documents written into Zipkin indices by third-party tools.
Related errors
- Invalid span, expecting annotations array start, got: {}
- Not a valid JSON object, start token: {}
- Not a valid JSON object, start token: %s
- End of input while parsing object.
- Incomplete annotation at {}
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/51f449f06e06d26d.
Report an issue: GitHub.