jaegertracing/jaeger · error
no metric backend configuration provided for '%s'
Error message
no metric backend configuration provided for '%s'
What it means
createMetricStorageFactory switches on which backend field is set in the MetricBackend config (Prometheus, Elasticsearch, Opensearch, ClickHouse). If the config exists under MetricBackends but none of the known backend fields is populated, the default branch sets this error, which is then wrapped as 'failed to initialize metrics storage'.
Source
Thrown at cmd/jaeger/internal/extension/jaegerstorage/extension.go:284
}
metricStoreFactory, err = esmetrics.NewFactory(
context.Background(),
*cfg.Opensearch,
osTelset,
httpAuth,
)
case cfg.ClickHouse != nil:
chTelset := telset
chTelset.Metrics = scopedMetricsFactory(name, "clickhouse", "metricstore")
metricStoreFactory, err = clickhouse.NewFactory(
context.Background(),
*cfg.ClickHouse,
chTelset,
)
default:
err = fmt.Errorf("no metric backend configuration provided for '%s'", name)
}
if err != nil {
return nil, fmt.Errorf("failed to initialize metrics storage '%s': %w", name, err)
}
return metricStoreFactory, nil
}
func (s *storageExt) MetricStorageFactory(name string) (storage.MetricStoreFactory, error) {
s.factoryMu.Lock()
defer s.factoryMu.Unlock()
// Return cached factory if already created
if mf, ok := s.metricsFactories[name]; ok {
return mf, nil
}
View on GitHub (pinned to 806f444784)
Solutions
- Populate exactly one supported backend (prometheus, elasticsearch, opensearch, or clickhouse) in the named metric backend entry
- Check for key typos in the metric backend YAML that silently leave all fields nil
- Ensure the config is being unmarshalled with mapstructure tags matching your YAML keys
Example fix
// before: typo'd key leaves all fields nil
metric_backends:
metrics-store:
prometeus:
endpoint: http://prom:9090
// after
metric_backends:
metrics-store:
prometheus:
endpoint: http://prom:9090 Defensive patterns
Strategy: validation
Validate before calling
// pre-check that a backend is selected
func hasMetricBackend(cfg jaegerstorage.MetricBackend) bool {
return cfg.Prometheus != nil || cfg.Elasticsearch != nil ||
cfg.Opensearch != nil || cfg.ClickHouse != nil
} Type guard
func metricBackendSelected(cfg jaegerstorage.MetricBackend) bool {
return cfg.Prometheus != nil || cfg.Elasticsearch != nil ||
cfg.Opensearch != nil || cfg.ClickHouse != nil
} Try / catch
mf, err := ext.MetricStorageFactory(name)
if err != nil {
if strings.Contains(err.Error(), "no metric backend configuration provided") {
return fmt.Errorf("metric backend '%s' has no backend type set (prometheus/elasticsearch/opensearch/clickhouse)", name)
}
return err
} Prevention
- Never declare an empty metric backend entry; set exactly one backend key
- Watch for YAML key typos that unmarshal to no known field
- Add a config linter that fails when a MetricBackend has all fields nil
When it happens
Trigger: MetricStorageFactory(name) finds the name in s.config.MetricBackends (so the not-declared check passes) but the MetricBackend struct has all backend pointers nil — the switch falls to default.
Common situations: A metric backend entry declared with an empty body or only unrecognized/typo'd keys (e.g. `prometeus:` instead of `prometheus:`) so no backend field is populated after unmarshalling.
Related errors
- cannot find metrics storage factory: %w
- cannot create metrics reader %w
- cannot find extension '%s' (make sure it's defined earlier i
- invalid configuration for trace storage '%s': %w
- invalid configuration for metric storage '%s': %w
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/8206cb7dd8accad7.
Report an issue: GitHub.