openzipkin/zipkin · error · IllegalArgumentException
Incomplete annotation at {}
Error message
Incomplete annotation at {} What it means
After parsing an annotation object, if timestamp == 0 or value == null it is considered incomplete and IllegalArgumentException('Incomplete annotation at <token>') is thrown. A timestamp of exactly 0 is treated as missing because real Zipkin timestamps are epoch-microseconds and never 0; a null value means the 'value' field was absent.
Source
Thrown at zipkin-storage/elasticsearch/src/main/java/zipkin2/elasticsearch/internal/JsonSerializers.java:183
long timestamp = 0;
String value = null;
while (parser.nextValue() != JsonToken.END_OBJECT) {
switch (parser.currentName()) {
case "timestamp":
timestamp = parser.getLongValue();
break;
case "value":
value = parser.getValueAsString();
break;
default:
// Skip
}
}
if (timestamp == 0 || value == null) {
throw new IllegalArgumentException("Incomplete annotation at " + parser.currentToken());
}
return Annotation.create(timestamp, value);
}
public static final ObjectParser<DependencyLink> DEPENDENCY_LINK_PARSER = parser -> {
if (!parser.isExpectedStartObjectToken()) {
throw new IllegalArgumentException("Expected start of dependency link object but was "
+ parser.currentToken());
}
DependencyLink.Builder result = DependencyLink.newBuilder();
JsonToken value;
while ((value = parser.nextValue()) != JsonToken.END_OBJECT) {
if (value == null) {
throw new IOException("End of input while parsing object.");
}
switch (parser.currentName()) {
case "parent":View on GitHub (pinned to 878ce2a1fa)
Solutions
- Ensure every annotation has both fields: {"timestamp":<epoch-micros>,"value":"..."} with timestamp > 0.
- Fix the producer to skip annotations lacking a timestamp instead of writing incomplete ones.
- Clean up or reindex malformed documents already stored.
- In Java code, Annotation.create(timestamp, value) requires the same pair — apply the same rule upstream.
Example fix
// before
{"annotations":[{"value":"sr"}]}
// -> IllegalArgumentException: Incomplete annotation at null
// after
{"annotations":[{"timestamp":1470150004000000,"value":"sr"}]} Defensive patterns
Strategy: validation
Validate before calling
for (JsonNode a : span.path("annotations")) {
if (!a.isObject() || a.path("timestamp").asLong(0) == 0 || !a.has("value")) {
throw new IOException("annotation missing timestamp(>0) or value: " + a);
}
} Type guard
boolean annotationComplete(JsonNode a) {
return a.isObject() && a.path("timestamp").isNumber() && a.path("timestamp").asLong() > 0
&& a.has("value") && !a.get("value").isNull();
} Try / catch
try { Span s = SPAN_PARSER.parse(p); }
catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Incomplete annotation")) {
// drop/reject the document and fix the producer to always set timestamp and value
}
} Prevention
- Every annotation needs timestamp (epoch-micros, > 0) and value.
- Drop incomplete annotations in producers instead of writing them.
- When porting legacy data, synthesize a timestamp rather than writing 0.
When it happens
Trigger: An annotation object missing 'timestamp' or 'value', or with timestamp: 0, e.g. {"value":"sr"} or {"timestamp":0,"value":"sr"}, inside the annotations array of a span being parsed.
Common situations: Fixtures written from memory that omit timestamps; converters dropping zero/absent timestamps; edge data where timestamp legitimately underflows to 0.
Related errors
- Not a valid JSON object, start token: %s
- 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: {}
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/747c41057f95d1fb.
Report an issue: GitHub.