openzipkin/zipkin · error · IllegalArgumentException
traceId == 0
Error message
traceId == 0
What it means
Thrown by the V1Span constructor (zipkin2.v1) when the builder's 64-bit traceId is 0. A span's traceId identifies the trace it belongs to; 0 is reserved to mean 'unset' in Zipkin, so constructing a V1 span without a real trace id is treated as a programming error.
Source
Thrown at zipkin/src/main/java/zipkin2/v1/V1Span.java:93
*/
public List<V1BinaryAnnotation> binaryAnnotations() {
return binaryAnnotations;
}
/** Same as {@link Span#debug()} */
public Boolean debug() {
return debug;
}
final long traceIdHigh, traceId, id;
final String name;
final long parentId, timestamp, duration;
final List<V1Annotation> annotations;
final List<V1BinaryAnnotation> binaryAnnotations;
final Boolean debug;
V1Span(Builder builder) {
if (builder.traceId == 0L) throw new IllegalArgumentException("traceId == 0");
if (builder.id == 0L) throw new IllegalArgumentException("id == 0");
this.traceId = builder.traceId;
this.traceIdHigh = builder.traceIdHigh;
this.name = builder.name;
this.id = builder.id;
this.parentId = builder.parentId;
this.timestamp = builder.timestamp;
this.duration = builder.duration;
this.annotations = sortedList(builder.annotations);
this.binaryAnnotations = sortedList(builder.binaryAnnotations);
this.debug = builder.debug;
}
public static Builder newBuilder() {
return new Builder();
}
public static final class Builder {View on GitHub (pinned to 878ce2a1fa)
Solutions
- Always supply a non-zero 64-bit trace id when constructing the V1Span builder
- If the id arrives as hex, validate parse output: reject empty strings and check the parsed long is != 0 before building
- Generate ids with a proper id generator (e.g. zipkin's or Brave's) instead of constants like 0L in tests
Example fix
// before
V1Span span = new V1Span.Builder(0L, 1L).name("get").build();
// after
V1Span span = new V1Span.Builder(0LL + traceIdFromContext, 1L).name("get").build(); Defensive patterns
Strategy: validation
Validate before calling
// validate before constructing the V1 span
if (traceId == 0L) {
throw new IllegalArgumentException(
"traceId is required: got 0 (unset or failed hex parse) for id=" + id);
}
V1Span span = new V1Span.Builder(traceId, id).name(name).build(); Try / catch
try {
return new V1Span.Builder(traceId, id).name(name).build();
} catch (IllegalArgumentException e) {
// drop or reject the malformed span record; never retry with the same ids
LOG.warn("Discarding span with invalid ids: traceId={}, id={}", traceId, id);
return null; // or route to a dead-letter path
} Prevention
- Validate upstream trace id strings: non-empty, hex-only, and parsed value != 0
- Use zipkin/Brave id generators for tests instead of 0L placeholders
- Fail instrumentation wiring at startup if no trace context is attached
When it happens
Trigger: Building a V1Span with new V1Span.Builder(0L, id); parsing v1 JSON where the 128-bit trace id string is malformed so the low 64 bits parse as 0; converting instrumentation data whose traceId field was never populated or was truncated to 0 by a hex-parsing bug.
Common situations: Custom instrumentation or a bridging layer (e.g. translating from another tracing system) that leaves traceId unset; lower-case/upper-case hex parsing that fails silently and returns 0; tests that build V1 spans with placeholder zero ids.
Related errors
AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14).
Data as JSON: /api/errors/8093850639ba0ae7.
Report an issue: GitHub.