{"record":{"id":"1ae578bcc7a009e9","repo":"grpc/grpc-java","slug":"invalid-input-expected-trace-id-at-offset-pos","errorCode":null,"errorMessage":"Invalid input: expected trace ID at offset ${pos}","messagePattern":"Invalid input: expected trace ID at offset (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"opentelemetry/src/main/java/io/grpc/opentelemetry/BinaryFormat.java","lineNumber":126,"sourceCode":"  @Override\n  public SpanContext parseBytes(byte[] serialized) {\n    checkNotNull(serialized, \"bytes\");\n    if (serialized.length == 0 || serialized[0] != VERSION_ID) {\n      throw new IllegalArgumentException(\"Unsupported version.\");\n    }\n    if (serialized.length < REQUIRED_FORMAT_LENGTH) {\n      throw new IllegalArgumentException(\"Invalid input: truncated\");\n    }\n    String traceId;\n    String spanId;\n    TraceFlags traceFlags = TraceFlags.getDefault();\n    int pos = 1;\n    if (serialized[pos] == TRACE_ID_FIELD_ID) {\n      traceId = TraceId.fromBytes(\n          Arrays.copyOfRange(serialized, pos + ID_SIZE, pos + ID_SIZE + TRACE_ID_SIZE));\n      pos += ID_SIZE + TRACE_ID_SIZE;\n    } else {\n      throw new IllegalArgumentException(\"Invalid input: expected trace ID at offset \" + pos);\n    }\n    if (serialized[pos] == SPAN_ID_FIELD_ID) {\n      spanId = SpanId.fromBytes(\n          Arrays.copyOfRange(serialized, pos + ID_SIZE, pos + ID_SIZE + SPAN_ID_SIZE));\n      pos += ID_SIZE + SPAN_ID_SIZE;\n    } else {\n      throw new IllegalArgumentException(\"Invalid input: expected span ID at offset \" + pos);\n    }\n    if (serialized.length > pos && serialized[pos] == TRACE_FLAG_FIELD_ID) {\n      if (serialized.length < ALL_FORMAT_LENGTH) {\n        throw new IllegalArgumentException(\"Invalid input: truncated\");\n      }\n      traceFlags = TraceFlags.fromByte(serialized[pos + ID_SIZE]);\n    }\n    return SpanContext.create(traceId, spanId, traceFlags, TraceState.getDefault());\n  }\n}\n","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/opentelemetry/src/main/java/io/grpc/opentelemetry/BinaryFormat.java#L108-L144","documentation":"BinaryFormat.parseBytes deserializes a SpanContext from the OpenTelemetry binary propagation format, which expects a version byte followed by the trace-ID field (field ID 0) with 16 bytes. This IllegalArgumentException is thrown when the byte at the trace-ID position is not the expected TRACE_ID_FIELD_ID, meaning the serialized bytes do not conform to the expected propagation format.","triggerScenarios":"Calling BinaryFormat.parseBytes (via the OpenTelemetry propagator's extract, e.g. SpanContext.fromByteArray or carrier extraction) with bytes whose second byte is not TRACE_ID_FIELD_ID (0x00) — i.e. a malformed, corrupted, or foreign-format binary span context.","commonSituations":"Interoperating with a service that emits a different binary propagation format (e.g. B3 binary or W3C traceparent encoded differently), bytes truncated to only the version byte, manual byte-array construction for tests, or an outdated/incompatible version of the propagator on the other side of the wire.","solutions":["Verify the incoming bytes were produced by the same OpenTelemetry binary format (version byte 0x00, then field ID 0x00 + 16-byte trace ID, then field ID 0x01 + 8-byte span ID, then optional trace-flags field).","Check that the upstream service uses the OpenTelemetry binary propagator, not B3 or another format; align propagators on both sides.","Inspect the raw bytes (hex dump) at offset 1 to confirm the field ID and that the array is at least 29 bytes long.","Wrap parseBytes in try-catch for IllegalArgumentException and fall back to treating the header as absent (no valid span context)."],"exampleFix":"// before\nSpanContext ctx = BinaryFormat.parseBytes(headerBytes);\n// after\nSpanContext ctx;\ntry {\n  ctx = BinaryFormat.parseBytes(headerBytes);\n} catch (IllegalArgumentException e) {\n  ctx = SpanContext.getInvalid();\n}","handlingStrategy":"try-catch","validationCode":"boolean isPlausibleOtelBinary(byte[] b) {\n  return b != null && b.length >= 1 && b[0] == 0 && b.length >= 29 && b[1] == 0;\n}","typeGuard":null,"tryCatchPattern":"try {\n  ctx = BinaryFormat.parseBytes(bytes);\n} catch (IllegalArgumentException e) {\n  ctx = SpanContext.getInvalid();\n}","preventionTips":["Use the same OpenTelemetry propagator on both ends of the wire.","Never hand-construct binary propagation bytes; always use the library's toByteArray.","Hex-inspect unknown propagation values before parsing.","Default to SpanContext.getInvalid() on parse failure so traces degrade gracefully."],"tags":["propagation","trace-context","deserialization","grpc"],"backgroundTag":"invalid-argument-format","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}