jaegertracing/jaeger · error
trace not found
Error message
trace not found
What it means
The Jaeger MCP get_critical_path handler queries the trace store by a single trace ID and requires exactly one matching trace. This error is thrown when GetTraces returns results but none match the requested trace ID (traceFound stays false), meaning the trace does not exist in storage. It surfaces as an MCP tool error to the caller, not a panic.
Source
Thrown at cmd/jaeger/internal/extension/jaegerquery/internal/mcptools/internal/handlers/get_critical_path.go:75
// Wrap with AggregateTraces to ensure each ptrace.Traces contains a complete trace
aggregatedIter := jptrace.AggregateTraces(tracesIter)
var trace ptrace.Traces
traceFound := false
for t, err := range aggregatedIter {
if err != nil {
return nil, types.GetCriticalPathOutput{}, fmt.Errorf("failed to get trace: %w", err)
}
traceFound = true
trace = t
break // We expect only one trace since we're querying by a single trace ID
}
if !traceFound {
return nil, types.GetCriticalPathOutput{}, errors.New("trace not found")
}
// Compute critical path
criticalPathSections, err := criticalpath.ComputeCriticalPathFromTraces(trace)
if err != nil {
return nil, types.GetCriticalPathOutput{}, fmt.Errorf("failed to compute critical path: %w", err)
}
// Build output
output := h.buildOutput(input.TraceID, trace, criticalPathSections)
return nil, output, nil
}
// buildQuery converts GetCriticalPathInput to querysvc.GetTraceParams.
func (*getCriticalPathHandler) buildQuery(input types.GetCriticalPathInput) (querysvc.GetTraceParams, error) {
// Validate input
if input.TraceID == "" {View on GitHub (pinned to 806f444784)
Solutions
- Verify the trace ID exists by fetching it first (get_trace / query API) before computing the critical path
- Check you are pointing the Jaeger query service at the same storage backend the trace was written to
- Confirm the trace is within the storage retention window and was not dropped by sampling
Example fix
// before
criticalPath, err := criticalPathTool.Handle(ctx, req, types.GetCriticalPathInput{TraceID: id})
// after
if _, err := getTraceTool.Handle(ctx, req, types.GetTraceInput{TraceID: id}); err != nil {
return nil, fmt.Errorf("trace %s not found in storage: %w", id, err)
}
criticalPath, err := criticalPathTool.Handle(ctx, req, types.GetCriticalPathInput{TraceID: id}) Defensive patterns
Strategy: validation
Validate before calling
func traceIDLooksValid(id string) bool {
if id == "" { return false }
_, err := hex.DecodeString(id)
return err == nil && (len(id) == 16 || len(id) == 32)
}
if !traceIDLooksValid(input.TraceID) { /* don't call; resolve a real ID */ } Try / catch
out, err := handler.Handle(ctx, req, input)
if err != nil {
if strings.Contains(err.Error(), "trace not found") {
// fall back: re-query the trace list or notify user the ID is absent
}
return err
} Prevention
- Look up the trace (get_trace) before computing derived analytics like critical path
- Keep trace IDs in one canonical lowercase-hex form end-to-end
- Check sampling and retention policies for the environment you query
- Verify query service and ingestion share the same storage backend
When it happens
Trigger: Calling the get_critical_path MCP tool with a trace_id that is valid hex but absent from the Jaeger storage backend; the query service returns zero traces or traces with a different ID, so the loop over results never sets traceFound.
Common situations: Copy-pasted trace ID from another environment (dev vs prod); trace aged out of retention and was dropped by storage TTL; sampling discarded the trace so it was never stored; typo in one hex digit; querying a replica that has not yet received the span.
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/904c4644c2520fca.
Report an issue: GitHub.