openzipkin/zipkin · error · NullPointerException

id == null

Error message

id == null

What it means

Span.Builder.id(String id) throws NullPointerException('id == null') when passed null. Unlike parentId and traceId, a span ID is mandatory — there is no 'unset id' state — so null is rejected immediately with NPE rather than IllegalArgumentException. This fails fast at setter time instead of at build().

Source

Thrown at zipkin/src/main/java/zipkin2/Span.java:455

      } else {
        this.parentId = length < 16 ? padLeft(parentId, 16) : parentId;
      }
      return this;
    }

    /**
     * Hex encodes the input as the {@link Span#id()} or throws IllegalArgumentException if the
     * input is zero.
     */
    public Builder id(long id) {
      if (id == 0L) throw new IllegalArgumentException("empty id");
      this.id = toLowerHex(id);
      return this;
    }

    /** Sets {@link Span#id()} or throws {@link IllegalArgumentException} if not lower-hex format. */
    public Builder id(String id) {
      if (id == null) throw new NullPointerException("id == null");
      int length = id.length();
      if (length == 0) throw new IllegalArgumentException("id is empty");
      if (length > 16) throw new IllegalArgumentException("id.length > 16");
      if (validateHexAndReturnZeroPrefix(id) == 16) {
        throw new IllegalArgumentException("id is all zeros");
      }
      this.id = length < 16 ? padLeft(id, 16) : id;
      return this;
    }

    /** Sets {@link Span#kind} */
    public Builder kind(@Nullable Kind kind) {
      this.kind = kind;
      return this;
    }

    /** Sets {@link Span#name} */
    public Builder name(@Nullable String name) {

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Check for null before calling and handle the missing-ID case (skip the span or start a new trace root).
  2. Fix header extraction to validate the B3/traceparent header set as a unit before building the span.
  3. If null can legitimately mean 'absent', generate a fresh span ID instead of forwarding null.

Example fix

// before
b.id(headers.get("x-b3-spanid"));

// after
String sid = headers.get("x-b3-spanid");
if (sid == null) sid = HexCodec.toLowerHex(ThreadLocalRandom.current().nextLong());
b.id(sid);
Defensive patterns

Strategy: validation

Validate before calling

String sid = headers.get("x-b3-spanid");
if (sid == null) sid = HexCodec.toLowerHex(ThreadLocalRandom.current().nextLong());
b.id(sid);

Prevention

When it happens

Trigger: Calling .id(someMap.get(key)) where the key is absent, or .id(header) where the header is missing and the extraction code returns null.

Common situations: Header-to-builder mapping code (x-b3-spanid, b3 single header) that assumes the header is always present; it is not when the caller is uninstrumented, headers are stripped by a proxy, or sampling dropped the context.

Related errors


AI-assisted analysis of openzipkin/zipkin@878ce2a1fa (2026-08-14). Data as JSON: /api/errors/dd940823a7690715. Report an issue: GitHub.