{"record":{"id":"dd940823a7690715","repo":"openzipkin/zipkin","slug":"id-null","errorCode":null,"errorMessage":"id == null","messagePattern":"id == null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/Span.java","lineNumber":455,"sourceCode":"      } else {\n        this.parentId = length < 16 ? padLeft(parentId, 16) : parentId;\n      }\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) {","sourceCodeStart":437,"sourceCodeEnd":473,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/Span.java#L437-L473","documentation":"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().","triggerScenarios":"Calling .id(someMap.get(key)) where the key is absent, or .id(header) where the header is missing and the extraction code returns null.","commonSituations":"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.","solutions":["Check for null before calling and handle the missing-ID case (skip the span or start a new trace root).","Fix header extraction to validate the B3/traceparent header set as a unit before building the span.","If null can legitimately mean 'absent', generate a fresh span ID instead of forwarding null."],"exampleFix":"// before\nb.id(headers.get(\"x-b3-spanid\"));\n\n// after\nString sid = headers.get(\"x-b3-spanid\");\nif (sid == null) sid = HexCodec.toLowerHex(ThreadLocalRandom.current().nextLong());\nb.id(sid);","handlingStrategy":"validation","validationCode":"String sid = headers.get(\"x-b3-spanid\");\nif (sid == null) sid = HexCodec.toLowerHex(ThreadLocalRandom.current().nextLong());\nb.id(sid);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass map.get/header results directly to id(String) without a null check.","Decide policy for missing span IDs (skip span vs generate new) in one shared helper."],"tags":["zipkin","span","span-id","null-pointer","builder"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}