jaegertracing/jaeger · warning

trace not found

Error message

trace not found

What it means

ErrTraceNotFound is the sentinel error declared in the v1 spanstore API that Reader.GetTrace implementations return when no spans exist for the requested trace ID. Callers are expected to check it with errors.Is so that 'trace missing' is treated as a normal, empty result (e.g. HTTP 404) rather than an internal failure. It is also propagated by helpers like unwrapNotFoundErr and gateway tryHandleError adapters.

Source

Thrown at internal/storage/v1/api/spanstore/interface.go:17

// Copyright (c) 2019 The Jaeger Authors.
// Copyright (c) 2017 Uber Technologies, Inc.
// SPDX-License-Identifier: Apache-2.0

package spanstore

import (
	"context"
	"errors"
	"time"

	"github.com/jaegertracing/jaeger-idl/model/v1"
	"github.com/jaegertracing/jaeger/internal/storage/v2/api/tracestore"
)

// ErrTraceNotFound is returned by Reader's GetTrace if no data is found for given trace ID.
var ErrTraceNotFound = errors.New("trace not found")

// Writer writes spans to storage.
type Writer interface {
	WriteSpan(ctx context.Context, span *model.Span) error
}

// Reader finds and loads traces and other data from storage.
type Reader interface {
	// GetTrace retrieves the trace with a given id.
	//
	// If no spans are stored for this trace, it returns ErrTraceNotFound.
	GetTrace(ctx context.Context, query GetTraceParameters) (*model.Trace, error)

	// GetServices returns all service names known to the backend from spans
	// within its retention period.
	GetServices(ctx context.Context) ([]string, error)

	// GetOperations returns all operation names for a given service

View on GitHub (pinned to 806f444784)

Solutions

  1. Check errors.Is(err, spanstore.ErrTraceNotFound) and treat it as 404 / empty result, not a server error.
  2. Verify the trace ID is correct (full 128-bit ID, no truncation or copy/paste artifacts).
  3. Confirm the query is hitting the same storage backend and tenant/namespace the trace was written to.
  4. If traces expire sooner than expected, increase the backend retention/TTL settings.
  5. If writing then immediately reading, ensure the write completed and became visible (account for buffering in the writer pipeline).

Example fix

// before
trace, err := reader.GetTrace(ctx, spanstore.GetTraceParameters{TraceID: id})
if err != nil {
	return err
}
// after
trace, err := reader.GetTrace(ctx, spanstore.GetTraceParameters{TraceID: id})
if errors.Is(err, spanstore.ErrTraceNotFound) {
	return nil, errNotFound // map to HTTP 404
}
if err != nil {
	return nil, err
}
Defensive patterns

Strategy: try-catch

Type guard

func isTraceNotFound(err error) bool {
	return errors.Is(err, spanstore.ErrTraceNotFound)
}

Try / catch

trace, err := reader.GetTrace(ctx, spanstore.GetTraceParameters{TraceID: id})
switch {
case errors.Is(err, spanstore.ErrTraceNotFound):
	return http.StatusNotFound // expected empty result
case err != nil:
	return http.StatusInternalServerError
}
return trace

Prevention

When it happens

Trigger: Calling GetTrace with a trace ID that was never written, has been TTL-aged out of storage, or was written to a different backend/namespace; also returned by ArchiveTrace and forwarded by tryHandleError paths when the underlying store reports no data.

Common situations: UI/user follows a link to an old trace that exceeded retention; wrong storage backend configured (e.g. pointing at an ES index without that trace); trace ID typo or truncated ID from a log line; tests that assert before the writer's async flush is visible to the reader.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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