{"record":{"id":"1a9f7a802b085072","repo":"cilium/cilium","slug":"registering-metric-w-1a9f7a","errorCode":null,"errorMessage":"registering metric: %w","messagePattern":"registering metric: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/metrics/features/operator/metrics.go","lineNumber":126,"sourceCode":"\t\tif k8sVersionStr := params.K8sVersion(); k8sVersionStr != \"\" {\n\t\t\tm.CPKubernetesVersion.WithLabelValues(k8sVersionStr).Set(1)\n\t\t}\n\t}\n}\n\nfunc (m Metrics) toGatherer() (prometheus.Gatherer, error) {\n\trv := reflect.ValueOf(m)\n\treg := prometheus.NewPedanticRegistry()\n\tfor _, f := range rv.Fields() {\n\t\tif !f.CanInterface() {\n\t\t\tcontinue\n\t\t}\n\t\tc, ok := reflect.TypeAssert[prometheus.Collector](f)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tif err := reg.Register(c); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"registering metric: %w\", err)\n\t\t}\n\t}\n\treturn reg, nil\n}\n","sourceCodeStart":108,"sourceCodeEnd":131,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/metrics/features/operator/metrics.go#L108-L131","documentation":"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.","triggerScenarios":"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'.","commonSituations":"Copy-pasting a metric definition and forgetting to change the name; a refactor merging two metric files causing name collisions.","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."],"exampleFix":"// before\nstatus: metric.New(...Subsystem: \"operator\", Name: \"status\"...),\nhealth: metric.New(...Subsystem: \"operator\", Name: \"status\"...),\n// after\nhealth: metric.New(...Subsystem: \"operator\", Name: \"health\"...),","handlingStrategy":"validation","validationCode":"scratch := prometheus.NewRegistry()\nfor _, c := range operatorCollectors {\n  if err := scratch.Register(c); err != nil { t.Fatalf(\"duplicate metric: %v\", err) }\n}","typeGuard":null,"tryCatchPattern":"if err := reg.Register(c); err != nil {\n  return nil, fmt.Errorf(\"registering metric %T: %w\", c, err)\n}","preventionTips":["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."],"tags":["prometheus","metrics","registration","cilium-operator"],"backgroundTag":"duplicate-metric-registration","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}