{"record":{"id":"8ba1105c86ea3047","repo":"openzipkin/zipkin","slug":"traceid-null","errorCode":null,"errorMessage":"traceId == null","messagePattern":"traceId == null","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"zipkin/src/main/java/zipkin2/Span.java","lineNumber":623,"sourceCode":"      }\n      return new Span(this);\n    }\n\n    Builder() {\n    }\n  }\n\n  @Override public String toString() {\n    return new String(SpanBytesEncoder.JSON_V2.encode(this), UTF_8);\n  }\n\n  /**\n   * Returns a valid lower-hex trace ID, padded left as needed to 16 or 32 characters.\n   *\n   * @throws IllegalArgumentException if oversized or not lower-hex\n   */\n  public static String normalizeTraceId(String traceId) {\n    if (traceId == null) throw new NullPointerException(\"traceId == null\");\n    int length = traceId.length();\n    if (length == 0) throw new IllegalArgumentException(\"traceId is empty\");\n    if (length > 32) throw new IllegalArgumentException(\"traceId.length > 32\");\n    int zeros = validateHexAndReturnZeroPrefix(traceId);\n    if (zeros == length) throw new IllegalArgumentException(\"traceId is all zeros\");\n    if (length == 32 || length == 16) {\n      if (length == 32 && zeros >= 16) return traceId.substring(16);\n      return traceId;\n    } else if (length < 16) {\n      return padLeft(traceId, 16);\n    } else {\n      return padLeft(traceId, 32);\n    }\n  }\n\n  static final String THIRTY_TWO_ZEROS;\n  static {\n    char[] zeros = new char[32];","sourceCodeStart":605,"sourceCodeEnd":641,"githubUrl":"https://github.com/openzipkin/zipkin/blob/878ce2a1fad54ca941d17fdcf2e1d924b148eb1f/zipkin/src/main/java/zipkin2/Span.java#L605-L641","documentation":"Span.normalizeTraceId(String) throws NullPointerException('traceId == null') when the argument is null. This static helper validates and pads a hex trace ID to 16 or 32 chars, and it is also called from Span.Builder.traceId(String). Null is rejected up front because there is no normalized representation of 'no trace ID'.","triggerScenarios":"Calling Span.normalizeTraceId(null) directly, or Span.Builder.traceId((String) null) — e.g. passing a value looked up from headers/MDC that was absent.","commonSituations":"Utility code that normalizes IDs read from B3 headers, MDC, or log correlation fields where the field may be missing; bridging code between Brave/other tracers and raw zipkin2 Span objects.","solutions":["Null-check before normalizing: treat null as 'no trace ID' and handle at the call site.","Fix the source of the null (missing header/context) rather than normalizing downstream.","If null is legitimate in your flow, wrap: id == null ? null : Span.normalizeTraceId(id)."],"exampleFix":"// before\nString traceId = Span.normalizeTraceId(mdc.get(\"traceId\"));\n\n// after\nString raw = mdc.get(\"traceId\");\nString traceId = raw == null ? null : Span.normalizeTraceId(raw);","handlingStrategy":"validation","validationCode":"String safe = raw == null ? null : Span.normalizeTraceId(raw);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Null-check any ID read from MDC/headers before normalizing.","Encapsulate 'read trace id' in one helper that returns Optional<String>."],"tags":["zipkin","trace-id","null-pointer","validation"],"backgroundTag":null,"analyzedSha":"878ce2a1fad54ca941d17fdcf2e1d924b148eb1f","analyzedAt":"2026-08-14T15:17:09.895Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}