jaegertracing/jaeger · error

cannot find factory for trace storage %s: %w

Error message

cannot find factory for trace storage %s: %w

What it means

jaeger-query's Start looks up the trace storage factory named in Storage.TracesPrimary via jaegerstorage.GetTraceStoreFactory. If no storage extension with that name is registered in the OTel collector host, the lookup fails and the error is wrapped as 'cannot find factory for trace storage %s'.

Source

Thrown at cmd/jaeger/internal/extension/jaegerquery/server.go:74

// begins serving queries, so it is ready when OnQuery/OnResult are invoked.
func (s *server) Dependencies() []component.ID {
	deps := make([]component.ID, 0, 1+len(s.config.QueryInterceptors))
	deps = append(deps, jaegerstorage.ID)
	deps = append(deps, s.config.QueryInterceptors...)
	return deps
}

func (s *server) Start(ctx context.Context, host component.Host) error {
	telset := telemetry.FromOtelComponent(s.telset, host)
	if !s.config.EnableTracing {
		telset.TracerProvider = nooptrace.NewTracerProvider()
	}
	telset.Metrics = telset.Metrics.
		Namespace(metrics.NSOptions{Name: "jaeger"}).
		Namespace(metrics.NSOptions{Name: "query"})
	tf, err := jaegerstorage.GetTraceStoreFactory(s.config.Storage.TracesPrimary, host)
	if err != nil {
		return fmt.Errorf("cannot find factory for trace storage %s: %w", s.config.Storage.TracesPrimary, err)
	}
	traceReader, err := tf.CreateTraceReader()
	if err != nil {
		return fmt.Errorf("cannot create trace reader: %w", err)
	}

	interceptors, err := queryinterceptor.Resolve(host, s.config.QueryInterceptors)
	if err != nil {
		return fmt.Errorf("cannot resolve query interceptors: %w", err)
	}

	df, ok := tf.(depstore.Factory)
	if !ok {
		return fmt.Errorf("cannot find factory for dependency storage %s: %w", s.config.Storage.TracesPrimary, err)
	}
	depReader, err := df.CreateDependencyReader()
	if err != nil {
		return fmt.Errorf("cannot create dependencies reader: %w", err)

View on GitHub (pinned to 806f444784)

Solutions

  1. Add/join the jaeger_storage extension whose name matches Storage.TracesPrimary in the same collector config
  2. Check the extension's own startup logs — if it failed to start it will not be registered
  3. Fix the spelling/case of the storage name under storage.traces_primary
  4. Verify the jaeger_storage extension is listed and healthy in the effective config

Example fix

// before
extensions:
  jaeger_query:
    storage:
      traces_primary: prodCass
dependencies:
  extensions: [jaeger_storage]
// after
extensions:
  jaeger_storage:
    backends:
      prod cassandra:
        cassandra: {}
  jaeger_query:
    storage:
      traces_primary: prod cassandra
Defensive patterns

Strategy: validation

Validate before calling

// Before deploy: verify the named backend exists in the jaeger_storage extension
import "github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerstorage"

func checkPrimary(name string, host component.Host) error {
	_, err := jaegerstorage.GetTraceStoreFactory(name, host)
	return err
}

Try / catch

if err := ext.Start(ctx, host); err != nil {
	if strings.Contains(err.Error(), "cannot find factory for trace storage") {
		log.Fatalf("storage %q missing: define it under extensions.jaeger_storage.backends", cfgName)
	}
	return err
}

Prevention

When it happens

Trigger: Starting the jaeger-query extension while config.Storage.TracesPrimary names a storage that is absent: no jaeger_storage extension defined, the extension failed to start, or the name is misspelled.

Common situations: Typos in the traces_primary storage name in the query extension config; forgetting to add a jaeger_storage extension to the collector config; running jaeger-query in a separate process without the storage extension deployed; extension startup ordering failure.

Related errors


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