jaegertracing/jaeger · error

invalid trace ID %q: %w

Error message

invalid trace ID %q: %w

What it means

traceIDFromHex converts a 32-character hex string into a pcommon.TraceID. If hex.DecodeString fails (non-hex characters or odd-length string), the input is wrapped as 'invalid trace ID %q' with the decode error attached. This happens when converting trace IDs from api_v3 string fields back to binary form.

Source

Thrown at cmd/jaeger/internal/integration/trace_reader.go:287

		}
	}
	return true
}

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

  1. Verify the trace ID string is exactly 32 hex characters (16 bytes) — e.g. with regexp ^[0-9a-f]{32}$ before decoding
  2. Get the trace ID from a reliable source (the jaeger UI/API copy button) rather than retyping it
  3. Strip any prefixes/separators (e.g. 'traceid=', whitespace, quotes) before parsing

Example fix

// before
id := "abcd-1234" // malformed
traceID, err := traceIDFromHex(id)
// after
id := strings.TrimSpace(rawID)
if matched, _ := regexp.MatchString(`^[0-9a-f]{32}$`, id); !matched {
    return fmt.Errorf("not a 32-char hex trace ID: %q", id)
}
traceID, err := traceIDFromHex(id)
Defensive patterns

Strategy: validation

Validate before calling

var traceIDHexRe = regexp.MustCompile(`^[0-9a-fA-F]{32}$`)
func validTraceIDHex(s string) bool { return traceIDHexRe.MatchString(s) }

Type guard

func isTraceIDString(s string) bool {
    return len(s) == 32 && regexp.MustCompile(`^[0-9a-fA-F]{32}$`).MatchString(s)
}

Try / catch

tid, err := traceIDFromHex(raw)
if err != nil {
    var he *hex.InvalidByteError
    if errors.As(err, &he) || errors.Is(err, hex.ErrLength) {
        return fmt.Errorf("bad trace id %q", raw)
    }
    return err
}

Prevention

When it happens

Trigger: GetTraceByName or similar paths parse a trace ID string that contains characters outside [0-9a-fA-F] or has an odd length, causing hex decoding to fail.

Common situations: Test fixtures or URLs containing malformed trace ID strings (e.g. 'abc', 'xyz123...', truncated or padded IDs); copying a trace ID that included non-hex separators; double-encoded or uppercase-containing values (those are fine) vs typos.

Related errors


AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01). Data as JSON: /api/errors/cb09ba268eb9dff2. Report an issue: GitHub.