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

  1. Populate exactly one supported backend (prometheus, elasticsearch, opensearch, or clickhouse) in the named metric backend entry
  2. Check for key typos in the metric backend YAML that silently leave all fields nil
  3. 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

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


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