jaegertracing/jaeger · error

trace storage '%s': %w

Error message

trace storage '%s': %w

What it means

This is the wrapper the top-level storage Config.Validate() adds when one named trace backend fails its own validation. The `%s` is the backend's name from jaeger.storage.trace_backends and the `%w` is the underlying error (e.g. `empty configuration` or `multiple backend types found for trace storage: ...`). It exists to tell you WHICH named backend is invalid.

Source

Thrown at cmd/internal/storageconfig/config.go:190

		backends = append(backends, "clickhouse")
	}
	if len(backends) == 0 {
		return errors.New("empty configuration")
	}
	if len(backends) > 1 {
		return fmt.Errorf("multiple backend types found for metric storage: %v", backends)
	}
	return nil
}

// Validate validates the storage configuration.
func (c *Config) Validate() error {
	if len(c.TraceBackends) == 0 {
		return errors.New("at least one storage backend is required")
	}
	for name, b := range c.TraceBackends {
		if err := b.Validate(); err != nil {
			return fmt.Errorf("trace storage '%s': %w", name, err)
		}
	}
	for name, b := range c.MetricBackends {
		if err := b.Validate(); err != nil {
			return fmt.Errorf("metric storage '%s': %w", name, err)
		}
	}
	return nil
}

View on GitHub (pinned to 806f444784)

Solutions

  1. Look at the backend name in the error (`trace storage 'NAME'`) and fix that entry in jaeger.storage.trace_backends under your config
  2. Ensure the named backend has exactly one populated storage type (memory, badger, cassandra, elasticsearch, grpc, or clickhouse)
  3. If the whole trace_backends map is empty, add at least one backend and reference it via jaeger.storage.backends
  4. Inspect the wrapped cause after '%w' — it states the precise validation failure

Example fix

// before (config.yaml)
jaeger:
  storage:
    trace_backends:
      main: {}   # empty
// after
jaeger:
  storage:
    trace_backends:
      main:
        memory:
          max_traces: 100000
Defensive patterns

Strategy: validation

Validate before calling

var cfg storageconfig.Config
if err := v.Unmarshal(&cfg); err != nil { return err }
if len(cfg.TraceBackends) == 0 {
    return errors.New("configure at least one entry under jaeger.storage.trace_backends")
}
for name, b := range cfg.TraceBackends {
    if err := b.Validate(); err != nil {
        return fmt.Errorf("pre-check trace backend %q: %w", name, err)
    }
}

Try / catch

if err := cfg.Validate(); err != nil {
    var name string
    if m := regexp.MustCompile(`trace storage '([^']+)'`).FindStringSubmatch(err.Error()); m != nil {
        name = m[1] // jump straight to the offending backend entry
    }
    return fmt.Errorf("fix jaeger.storage.trace_backends entry %q: %w", name, err)
}

Prevention

When it happens

Trigger: Calling Config.Validate() (during Jaeger config load) where any entry in TraceBackends returns an error from TraceBackend.Validate — zero backends configured entirely also fails earlier with 'at least one storage backend is required'.

Common situations: A named backend left empty after removing its type field; typos in the backend type key so nothing unmarshals; merged configs that blank out a backend's body.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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