jaegertracing/jaeger · error
invalid TraceID length: %d
Error message
invalid TraceID length: %d
What it means
TraceID.UnmarshalJSON decodes a base64-encoded trace ID string from JSON and requires the decoded bytes to be exactly 16 bytes (128 bits), the fixed Cassandra storage width. If the JSON field holds a base64 string that decodes to any other length, the unmarshal fails with this error rather than silently producing a zero-padded or truncated trace ID.
Source
Thrown at internal/storage/v1/cassandra/spanstore/dbmodel/ids.go:45
func (t TraceID) MarshalJSON() ([]byte, error) {
var out [26]byte
out[0] = '"'
base64.StdEncoding.Encode(out[1:25], t[:])
out[25] = '"'
return out[:], nil
}
func (t *TraceID) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return err
}
if len(b) != 16 {
return fmt.Errorf("invalid TraceID length: %d", len(b))
}
copy(t[:], b)
return nil
}
View on GitHub (pinned to 806f444784)
Solutions
- Base64-encode the 16-byte trace ID (std encoding) before writing it into JSON.
- If the source IDs are hex, convert hex string to 16 raw bytes and then base64-encode, e.g. hex.DecodeString then base64.StdEncoding.EncodeToString.
- For 64-bit legacy IDs, left-pad to 16 bytes before encoding, matching Jaeger's zero-padded 128-bit representation.
- Check the producing system's serialization format and align it with dbmodel.TraceID's expected base64-of-16-bytes form.
Example fix
// before
json := `{"trace_id":"00000000000000000000000000000001"}` // hex, decodes to 22 raw bytes
// after
b := make([]byte, 16)
binary.BigEndian.PutUint64(b[8:], 1)
json := fmt.Sprintf(`{"trace_id":"%s"}`, base64.StdEncoding.EncodeToString(b)) Defensive patterns
Strategy: validation
Validate before calling
b, err := base64.StdEncoding.DecodeString(idStr)
if err != nil || len(b) != 16 {
return fmt.Errorf("trace ID must be base64 of exactly 16 bytes, got %d bytes", len(b))
} Type guard
func isValidTraceID(s string) bool {
b, err := base64.StdEncoding.DecodeString(s)
return err == nil && len(b) == 16
} Try / catch
var id dbmodel.TraceID
if err := json.Unmarshal(data, &id); err != nil {
// handle invalid-length/encoding trace ID before use
return fmt.Errorf("bad trace id in payload: %w", err)
} Prevention
- Always serialize trace IDs as base64 of the raw 16 bytes.
- Convert hex-encoded IDs to 16 bytes before encoding for Jaeger's storage model.
- Add a round-trip test (marshal then unmarshal) for trace ID fixtures.
- Zero-pad 64-bit legacy IDs to 128 bits.
When it happens
Trigger: Unmarshalling JSON (via encoding/json or gocql) into dbmodel.TraceID where the string field is not base64 of exactly 16 bytes — e.g. a hex string like "00000000000000000000000000000001" without base64 encoding, an empty string, or a 8-byte/24-byte value.
Common situations: Importing traces from another storage backend that serializes trace IDs as hex or as 8-byte IDs (Zipkin-style 64-bit IDs); hand-crafted JSON fixtures in tests; a migration tool writing the wrong encoding.
Related errors
- TraceID is not a 128bit integer
- unknown column for position: %q
- trace_ttl can either be 0 or greater than or equal to 1 seco
- dependencies_ttl can either be 0 or greater than or equal to
- compaction_window should at least be 1 minute
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/4ef233c0a99c40da.
Report an issue: GitHub.