{"record":{"id":"366c3c1ee1b24e68","repo":"openzipkin/zipkin","slug":"id-is-empty","errorCode":null,"errorMessage":"id is empty","messagePattern":"id is empty","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/Span.java","lineNumber":457,"sourceCode":"      }\n      return this;\n    }\n\n    /**\n     * Hex encodes the input as the {@link Span#id()} or throws IllegalArgumentException if the\n     * input is zero.\n     */\n    public Builder id(long id) {\n      if (id == 0L) throw new IllegalArgumentException(\"empty id\");\n      this.id = toLowerHex(id);\n      return this;\n    }\n\n    /** Sets {@link Span#id()} or throws {@link IllegalArgumentException} if not lower-hex format. */\n    public Builder id(String id) {\n      if (id == null) throw new NullPointerException(\"id == null\");\n      int length = id.length();\n      if (length == 0) throw new IllegalArgumentException(\"id is empty\");\n      if (length > 16) throw new IllegalArgumentException(\"id.length > 16\");\n      if (validateHexAndReturnZeroPrefix(id) == 16) {\n        throw new IllegalArgumentException(\"id is all zeros\");\n      }\n      this.id = length < 16 ? padLeft(id, 16) : id;\n      return this;\n    }\n\n    /** Sets {@link Span#kind} */\n    public Builder kind(@Nullable Kind kind) {\n      this.kind = kind;\n      return this;\n    }\n\n    /** Sets {@link Span#name} */\n    public Builder name(@Nullable String name) {\n      this.name = name == null || name.isEmpty() ? null : name.toLowerCase(Locale.ROOT);\n      return this;","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/Span.java#L439-L475","documentation":"Span.Builder.id(String id) throws IllegalArgumentException('id is empty') when the argument is non-null but has length 0. An empty string is not a valid lower-hex span ID (valid ones are 1-16 hex chars, padded to 16 internally). The check runs before the length>16 and hex checks.","triggerScenarios":"Calling .id(\"\") directly, or passing a header value, substring, or trimmed string that ended up as the empty string.","commonSituations":"Mapping x-b3-spanid or the b3 single header into the builder without normalizing blank values; buggy header parsing (e.g. split(\"-\")[1] on a malformed b3 header) that yields an empty segment.","solutions":["Validate the extracted ID is non-empty before calling the builder; treat blank as missing.","Parse the b3 single header with a strict parser instead of String.split so malformed headers fail loudly upstream.","Fall back to generating a new span ID when the incoming value is blank."],"exampleFix":"// before\nb.id(b3Header.split(\"-\")[1]);\n\n// after\nString[] parts = b3Header.split(\"-\");\nString sid = parts.length > 1 && !parts[1].isEmpty() ? parts[1] : null;\nb.id(sid != null ? sid : HexCodec.toLowerHex(ThreadLocalRandom.current().nextLong()));","handlingStrategy":"validation","validationCode":"boolean validSpanId(String s) {\n  return s != null && !s.isEmpty() && s.matches(\"[0-9a-f]{1,16}\")\n      && s.chars().anyMatch(c -> c != '0');\n}\n// if (validSpanId(sid)) b.id(sid); else b.id(newIdHex());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Parse b3/traceparent headers with a strict parser, not String.split.","Validate all incoming ID strings with one shared lower-hex validator."],"tags":["zipkin","span","span-id","validation","builder"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}