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

  1. Verify the trace exists with a direct trace lookup first
  2. Retry after a short delay if the trace was just emitted (ingestion lag)
  3. Confirm storage backend, retention window, and tenant/namespace match the writer
  4. 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

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


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