jaegertracing/jaeger · error
invalid span_id %q: %w
Error message
invalid span_id %q: %w
What it means
Each entry in input.SpanIDs is validated with parseSpanID before querying. A malformed span ID (wrong hex format or length) aborts the whole request with "invalid span_id \"<value>\": <reason>". The message quotes the offending value so the client can fix exactly that entry; validation happens up front to avoid a doomed backend query.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_span_details.go:156
len(input.SpanIDs),
h.maxSpanDetailsPerRequest,
)
}
traceID, err := parseTraceID(input.TraceID)
if err != nil {
return querysvc.GetTraceParams{}, nil, fmt.Errorf("invalid trace_id: %w", err)
}
// Validate every span_id up front so a malformed value fails fast instead of
// triggering a backend query that can never match a real span ID. Collect the
// canonical lowercase hex form so the lookup set agrees with the ID the trace
// iterator emits regardless of the request's casing.
canonicalSpanIDs := make([]string, 0, len(input.SpanIDs))
for _, spanIDStr := range input.SpanIDs {
spanID, err := parseSpanID(spanIDStr)
if err != nil {
return querysvc.GetTraceParams{}, nil, fmt.Errorf("invalid span_id %q: %w", spanIDStr, err)
}
canonicalSpanIDs = append(canonicalSpanIDs, spanID.String())
}
return querysvc.GetTraceParams{
TraceIDs: []tracestore.GetTraceParams{
{TraceID: traceID},
},
RawTraces: false, // We want adjusted traces
}, canonicalSpanIDs, nil
}
// buildSpanDetail constructs a SpanDetail from a ptrace.Span.
func buildSpanDetail(pos jptrace.SpanIterPos, span ptrace.Span) types.SpanDetail {
// Get service name from resource attributes
serviceName := ""
if svc, ok := pos.Resource.Resource().Attributes().Get("service.name"); ok {
serviceName = svc.Str()View on GitHub (pinned to 806f444784)
Solutions
- Fix the quoted span ID to be valid hex of the expected length.
- Remove or correct empty/placeholder entries in the span_ids array.
- Ensure IDs are passed as separate array elements, not a delimited string.
- Decode from the correct representation: span IDs in Jaeger API/OTLP are hex strings, not raw bytes or base64.
Example fix
// before SpanIDs: ["abc", "7c4485"+"-01"] // after SpanIDs: ["bf39692569d65829", "7c44850100000000"]
Defensive patterns
Strategy: validation
Validate before calling
func validSpanID(s string) bool {
if len(s) != 16 { return false } // pcommon.SpanID is 8 bytes
_, err := hex.DecodeString(s)
return err == nil
}
// filter: spanIDs = slices.DeleteFunc(spanIDs, func(id string) bool { return !validSpanID(id) }) Type guard
func normalizeSpanID(s string) (string, bool) {
s = strings.TrimPrefix(strings.TrimSpace(s), "0x")
if _, err := hex.DecodeString(s); err != nil || len(s) == 0 { return "", false }
return strings.ToLower(s), true
} Try / catch
out, _, err := handler.Handle(ctx, req, input)
if err != nil && strings.HasPrefix(err.Error(), "invalid span_id") {
var bad string
fmt.Sscanf(err.Error(), "invalid span_id %q", &bad)
input.SpanIDs = slices.DeleteFunc(input.SpanIDs, func(id string) bool { return id == bad })
out, _, err = handler.Handle(ctx, req, input)
} Prevention
- Validate every span ID as hex before adding it to span_ids.
- Pass IDs as separate array elements, never a delimited string.
- Use hex span IDs exactly as returned by the Jaeger API, not decoded bytes.
- Parse the quoted offending ID from the error to auto-clean the list.
When it happens
Trigger: Calling get_span_details with any SpanIDs element that parseSpanID rejects: non-hex characters, empty string, wrong length for pcommon.SpanID, or an ID containing separators/prefixes.
Common situations: Span IDs copied from spans/JSON attributes that were already hex-decoded or base64-encoded; mixing 8-byte span IDs from other instrumentation with the expected format; list built by concatenating IDs with commas instead of separate array elements.
Related errors
- span ID must not be all zero
- trace_id is required
- start_time must be before end_time
- trace_id is required
- span_ids is required and must not be empty
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/e05188ec29c36cf9.
Report an issue: GitHub.