openzipkin/zipkin · error · IllegalArgumentException

parentId is empty

Error message

parentId is empty

What it means

Span.Builder.parentId(String) throws IllegalArgumentException('parentId is empty') when the argument is a non-null, zero-length string. An empty string is neither a valid ID nor the canonical way to say 'no parent' — that is null (or a zero-valued ID, which this method converts to null). The check happens before length/hex validation.

Source

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

    }

    /** Hex encodes the input as the {@link Span#parentId()} or unsets if the input is zero. */
    public Builder parentId(long parentId) {
      this.parentId = parentId != 0L ? toLowerHex(parentId) : null;
      return this;
    }

    /**
     * Sets {@link Span#parentId()} or throws {@link IllegalArgumentException} if not lower-hex
     * format.
     */
    public Builder parentId(@Nullable String parentId) {
      if (parentId == null) {
        this.parentId = null;
        return this;
      }
      int length = parentId.length();
      if (length == 0) throw new IllegalArgumentException("parentId is empty");
      if (length > 16) throw new IllegalArgumentException("parentId.length > 16");
      if (validateHexAndReturnZeroPrefix(parentId) == length) {
        this.parentId = null;
      } 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;
    }

View on GitHub (pinned to 878ce2a1fa)

Solutions

  1. Convert empty to null before calling: .parentId(isEmpty(parentId) ? null : parentId).
  2. Guard at the extraction boundary: treat a blank header as 'no parent span' when reading B3/traceparent headers.
  3. Log which header produced the blank value so misconfigured upstream services can be identified.

Example fix

// before
b.parentId(request.getHeader("x-b3-parentspanid"));

// after
String p = request.getHeader("x-b3-parentspanid");
b.parentId(p == null || p.isEmpty() ? null : p);
Defensive patterns

Strategy: validation

Validate before calling

String normalizeParentId(String p) {
  return (p == null || p.isEmpty()) ? null : p;
}
// b.parentId(normalizeParentId(header));

Prevention

When it happens

Trigger: Calling .parentId("") or parentId(someHeader) where the header was present but blank; passing a substring or trimmed value that ended up empty.

Common situations: Forwarding parent-span headers (x-b3-parentspanid, traceparent's parent-id part) into the builder without checking for blank values — common in proxies, filters, and Spring HandlerInterceptors that map headers 1:1 to builder calls.

Related errors


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