{"record":{"id":"381d704d6ed1ce61","repo":"openzipkin/zipkin","slug":"empty-trace-id","errorCode":null,"errorMessage":"empty trace ID","messagePattern":"empty trace ID","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/Span.java","lineNumber":405,"sourceCode":"    }\n\n    /**\n     * Sets {@link Span#id()} or throws {@link IllegalArgumentException} if not lower-hex format.\n     */\n    public Builder traceId(String traceId) {\n      this.traceId = normalizeTraceId(traceId);\n      return this;\n    }\n\n    /**\n     * Encodes 64 or 128 bits from the input into a hex trace ID.\n     *\n     * @param high Upper 64bits of the trace ID. Zero means the trace ID is 64-bit.\n     * @param low Lower 64bits of the trace ID.\n     * @throws IllegalArgumentException if both values are zero\n     */\n    public Builder traceId(long high, long low) {\n      if (high == 0L && low == 0L) throw new IllegalArgumentException(\"empty trace ID\");\n      char[] data = RecyclableBuffers.shortStringBuffer();\n      int pos = 0;\n      if (high != 0L) {\n        writeHexLong(data, pos, high);\n        pos += 16;\n      }\n      writeHexLong(data, pos, low);\n      this.traceId = new String(data, 0, high != 0L ? 32 : 16);\n      return this;\n    }\n\n    /** Hex encodes the input as the {@link Span#parentId()} or unsets if the input is zero. */\n    public Builder parentId(long parentId) {\n      this.parentId = parentId != 0L ? toLowerHex(parentId) : null;\n      return this;\n    }\n\n    /**","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/Span.java#L387-L423","documentation":"Span.Builder.traceId(long high, long low) encodes a 64- or 128-bit trace ID from two longs and throws IllegalArgumentException('empty trace ID') when both high and low are zero. A trace ID of all zeros is invalid in the Zipkin/B3 data model because it cannot uniquely identify a trace. The guard runs before any hex encoding happens, so the builder state is left untouched.","triggerScenarios":"Calling Span.newBuilder().traceId(0L, 0L), or traceId(high, low) where both values came from an uninitialized long field, a defaulted primitive, or a parsed value that silently defaulted to 0 on error.","commonSituations":"Instrumentation code that reads trace IDs from headers/context objects that were missing (so the parsed long stayed 0), porting code from a tracer that represents 'no trace' as zero, or test fixtures generated with new Random() seeds of 0.","solutions":["Skip creating the span when both longs are zero: treat zero as 'no active trace' rather than passing it through.","Trace the origin of the two longs (e.g. B3 single-header or traceparent parsing) and fix the upstream parser so a missing ID is surfaced as null/absent, not 0.","If the ID arrives as a hex string, use Span.Builder.traceId(String) or Span.normalizeTraceId instead of converting to longs yourself."],"exampleFix":"// before\nspan = Span.newBuilder().traceId(high, low).id(spanId).build();\n\n// after\nif (high == 0L && low == 0L) return null; // no active trace\nspan = Span.newBuilder().traceId(high, low).id(spanId).build();","handlingStrategy":"validation","validationCode":"boolean hasTraceId(long high, long low) {\n  return high != 0L || low != 0L;\n}\n// use: if (hasTraceId(high, low)) b.traceId(high, low); else startNewTrace();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat 0L/0L as 'no active trace' at extraction time; never forward zeros into the builder.","Prefer the String overloads (traceId(String)) when IDs originate as hex text."],"tags":["zipkin","span","trace-id","validation","builder"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}