jaegertracing/jaeger · error
at least one storage backend is required
Error message
at least one storage backend is required
What it means
errUnsupportedField reports that the named built-in field of the given level (a reference like duration, service name, etc.) is not supported by this backend's filter engine. The filter is rejected with tracestore.ErrFilterUnsupported since the engine has no mapping from that built-in field to an indexed Elasticsearch field.
Source
Thrown at cmd/internal/storageconfig/config.go:186
if cfg.Opensearch != nil {
backends = append(backends, "opensearch")
}
if cfg.ClickHouse != nil {
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
- Use a built-in field name the backend supports (verify against the tracestore's field list/capabilities).
- Move the value into a span attribute and filter on the attribute instead of the unsupported built-in field.
- Upgrade the backend if the field is supported in a newer version.
Example fix
// before
{"field": "client.city", "op": "eq", "value": "NYC"}
// after
{"attr": "client.city", "op": "eq", "value": "NYC"} Defensive patterns
Strategy: validation
Validate before calling
var builtinFields = map[string]bool{"duration": true, /* ...supported set... */ }
func fieldSupported(name string) bool { return builtinFields[name] } Try / catch
q, err := buildComparison(ref, op, value)
if errors.Is(err, tracestore.ErrFilterUnsupported) && strings.Contains(err.Error(), "built-in field") {
// use a supported field or an attribute instead
} Prevention
- Verify built-in field names against the deployed backend version.
- Prefer span attributes for fields outside the supported built-in set.
- Add integration tests covering every filter field you emit.
When it happens
Trigger: Submitting a filter that dereferences a built-in field on a level where buildComparison/buildExists has no case for it — e.g. a built-in field name that exists in the expression model but is not mapped in this tracestore.
Common situations: Using a field added in a newer expression model than the deployed backend supports; typos or case differences in built-in field names; copying filters from backends with richer built-in field sets.
Related errors
- file must begin with '['
- empty configuration
- cannot assign unique span ID, too many spans in the trace
- max spans count reached
- only one of basic auth (--es.username/--es.password), --es.t
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/18021911dcb60fc6.
Report an issue: GitHub.