jaegertracing/jaeger · error
trace ID must be 16 bytes, got %d
Error message
trace ID must be 16 bytes, got %d
What it means
After successful hex decoding, traceIDFromHex verifies the decoded byte slice is exactly 16 bytes, as required by pcommon.TraceID. A shorter or longer (but still valid hex) string is rejected with 'trace ID must be 16 bytes, got %d'. A 32-hex-char string decodes to exactly 16 bytes, so this fires for hex strings of any other even length.
Source
Thrown at cmd/jaeger/internal/integration/trace_reader.go:290
}
func unwrapNotFoundErr(err error) error {
if s, _ := status.FromError(err); s != nil {
if strings.Contains(s.Message(), spanstore.ErrTraceNotFound.Error()) {
return spanstore.ErrTraceNotFound
}
}
return err
}
// traceIDFromHex parses a 32-character hex string into a pcommon.TraceID.
func traceIDFromHex(s string) (pcommon.TraceID, error) {
b, err := hex.DecodeString(s)
if err != nil {
return pcommon.TraceID{}, fmt.Errorf("invalid trace ID %q: %w", s, err)
}
if len(b) != 16 {
return pcommon.TraceID{}, fmt.Errorf("trace ID must be 16 bytes, got %d", len(b))
}
return pcommon.TraceID(b), nil
}
View on GitHub (pinned to 806f444784)
Solutions
- Ensure the input is exactly 32 hex characters before calling; trim or validate length
- If you have a span ID (16 hex chars), do not feed it as a trace ID — use the correct field
- For variable-length sources, pad/left-align legacy 8-byte trace IDs to 16 bytes only if that is the intended semantic
Example fix
// before
traceID, err := traceIDFromHex(spanIDHex) // 16 hex chars = 8 bytes
// after
if len(traceIDHex) != 32 {
return fmt.Errorf("trace ID must be 32 hex chars, got %d", len(traceIDHex))
}
traceID, err := traceIDFromHex(traceIDHex) Defensive patterns
Strategy: validation
Validate before calling
func hasTraceIDLength(s string) bool { return len(s) == 32 } // 32 hex chars == 16 bytes Try / catch
tid, err := traceIDFromHex(s)
if err != nil {
if strings.HasPrefix(err.Error(), "trace ID must be 16 bytes") {
return fmt.Errorf("%q is not a trace ID (span ID or foreign ID?)", s)
}
return err
} Prevention
- Distinguish trace IDs (32 hex chars) from span IDs (16 hex chars) in your data model
- Validate length at ingestion/URL-routing time, before deep parsing
- Pad legacy 8-byte trace IDs deliberately, only where semantics allow
When it happens
Trigger: Parsing a hex string like 16 or 64 hex characters that decodes cleanly but is not 16 bytes — e.g. span IDs (8 bytes) passed where trace IDs are expected, or concatenated trace+span IDs.
Common situations: Passing a span ID instead of a trace ID; pasting a 64-hex-char 128-bit trace ID from another tracing system (W3C allows 16-byte, but 8-byte IDs from legacy systems are common); slicing errors in test data generators.
Related errors
- invalid trace_id: %w
- invalid trace_id: %w
- trace ID must be 32 hex characters, got %d
- invalid trace ID %q: %w
- trace_id is required
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/cc78e53a0675e8d4.
Report an issue: GitHub.