jaegertracing/jaeger · error
trace not found
Error message
trace not found
What it means
The get_trace_errors MCP handler fetches the trace by ID and scans its spans for error tags. This error is thrown when no trace matching the requested trace ID is found (traceFound stays false), so there is nothing to scan for errors.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_trace_errors.go:85
traceFound = true
// Iterate through all spans in the trace
for pos, span := range jptrace.SpanIter(trace) {
// Check if span has error status
if span.Status().Code() == ptrace.StatusCodeError {
totalErrors++
// Only build and collect detail up to the limit
if h.maxSpanDetailsPerRequest == 0 || len(errorSpans) < h.maxSpanDetailsPerRequest {
detail := buildSpanDetail(pos, span)
errorSpans = append(errorSpans, detail)
}
}
}
}
if !traceFound {
return nil, types.GetTraceErrorsOutput{}, errors.New("trace not found")
}
output := types.GetTraceErrorsOutput{
TraceID: input.TraceID,
TotalErrorCount: totalErrors,
Spans: errorSpans,
}
return nil, output, nil
}
// buildQuery converts GetTraceErrorsInput to querysvc.GetTraceParams.
func (*getTraceErrorsHandler) buildQuery(input types.GetTraceErrorsInput) (querysvc.GetTraceParams, error) {
// Validate input
if input.TraceID == "" {
return querysvc.GetTraceParams{}, errors.New("trace_id is required")
}
View on GitHub (pinned to 806f444784)
Solutions
- Verify the trace exists with a direct trace lookup first
- Retry after a short delay if the trace was just emitted (ingestion lag)
- Confirm storage backend, retention window, and tenant/namespace match the writer
- Re-check the trace ID for typos
Example fix
// before
out, err := traceErrors.Handle(ctx, req, types.GetTraceErrorsInput{TraceID: id})
// after
out, err := traceErrors.Handle(ctx, req, types.GetTraceErrorsInput{TraceID: id})
if err != nil && strings.Contains(err.Error(), "trace not found") {
time.Sleep(2 * time.Second) // allow ingestion lag
out, err = traceErrors.Handle(ctx, req, types.GetTraceErrorsInput{TraceID: id})
} Defensive patterns
Strategy: try-catch
Validate before calling
func validateTraceErrorsInput(in types.GetTraceErrorsInput) error {
if in.TraceID == "" { return errors.New("trace_id required") }
if _, err := hex.DecodeString(in.TraceID); err != nil { return fmt.Errorf("bad trace_id: %w", err) }
return nil
} Try / catch
out, err := handler.Handle(ctx, req, input)
if err != nil {
if strings.Contains(err.Error(), "trace not found") {
// retry once after a delay (ingestion lag), then surface as user-facing "trace unavailable"
time.Sleep(2 * time.Second)
out, err = handler.Handle(ctx, req, input)
}
if err != nil { return err }
} Prevention
- Retry transient not-found shortly after trace emission to absorb ingestion lag
- Check retention/sampling config for the query environment
- Canonicalize trace IDs to lowercase hex before querying
When it happens
Trigger: Calling get_trace_errors with a trace_id that does not exist in the storage backend; GetTraces yields no matching trace so the error is returned instead of an output with zero errors.
Common situations: Querying before the trace finished being ingested (write lag); retention expiry; sampling dropped the trace; wrong cluster/tenant; ID typo.
Related errors
- trace not found
- trace not found
- failed to get dependencies: %w
- failed to get services: %w
- failed to get trace: %w
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/ba9daa91615f71ac.
Report an issue: GitHub.