cilium/cilium · error
registering metric: %w
Error message
registering metric: %w
What it means
The operator's metrics package has its own toGatherer (pkg/metrics/features/operator/metrics.go:126) that registers every prometheus.Collector field of its metrics struct onto a fresh registry. reg.Register returning false/error surfaces as 'registering metric: %w', almost always a duplicate fully-qualified metric name between two fields.
Source
Thrown at pkg/metrics/features/operator/metrics.go:126
if k8sVersionStr := params.K8sVersion(); k8sVersionStr != "" {
m.CPKubernetesVersion.WithLabelValues(k8sVersionStr).Set(1)
}
}
}
func (m Metrics) toGatherer() (prometheus.Gatherer, error) {
rv := reflect.ValueOf(m)
reg := prometheus.NewPedanticRegistry()
for _, f := range rv.Fields() {
if !f.CanInterface() {
continue
}
c, ok := reflect.TypeAssert[prometheus.Collector](f)
if !ok {
continue
}
if err := reg.Register(c); err != nil {
return nil, fmt.Errorf("registering metric: %w", err)
}
}
return reg, nil
}
View on GitHub (pinned to ac7b90affa)
Solutions
- Inspect the wrapped error for 'duplicate metrics collector registration attempted' and give the colliding metric a unique name.
- Verify namespace/subsystem/name uniqueness across the operator metrics struct.
- If the same collector instance appears in two fields, keep only one field.
Example fix
// before status: metric.New(...Subsystem: "operator", Name: "status"...), health: metric.New(...Subsystem: "operator", Name: "status"...), // after health: metric.New(...Subsystem: "operator", Name: "health"...),
Defensive patterns
Strategy: validation
Validate before calling
scratch := prometheus.NewRegistry()
for _, c := range operatorCollectors {
if err := scratch.Register(c); err != nil { t.Fatalf("duplicate metric: %v", err) }
} Try / catch
if err := reg.Register(c); err != nil {
return nil, fmt.Errorf("registering metric %T: %w", c, err)
} Prevention
- Keep one canonical metrics struct per component and verify FQ name uniqueness.
- Add a CI test that builds the operator gatherer.
- When copy-pasting metric definitions, change subsystem/name immediately.
When it happens
Trigger: Two fields in the operator metrics struct share the same metric namespace/subsystem/name, so the second Register call fails with 'duplicate metrics collector registration attempted'.
Common situations: Copy-pasting a metric definition and forgetting to change the name; a refactor merging two metric files causing name collisions.
Related errors
- registering metric: %w
- metric %s is not a Counter: %v
- metric %s did not increase as expected, value 1 was assumed
- metric %s has different length metrics 1: %d and metrics 2:
- metric %s did not increase as expected, value 1: %f and valu
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/1a9f7a802b085072.
Report an issue: GitHub.