{"record":{"id":"1cd9974277fa8fb9","repo":"cilium/cilium","slug":"failed-to-unregister-metric-dns-response-types-to","errorCode":null,"errorMessage":"failed to unregister metric: dns_response_types_total,","messagePattern":"failed to unregister metric: dns_response_types_total,","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/hubble/metrics/dns/handler.go","lineNumber":180,"sourceCode":"\t\t\t\tnewLabels = append(newLabels, dns.Query)\n\t\t\t}\n\t\t\th.responseTypes.WithLabelValues(newLabels...).Inc()\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (h *dnsHandler) Deinit(registry *prometheus.Registry) error {\n\tvar errs error\n\tif !registry.Unregister(h.queries) {\n\t\terrs = errors.Join(errs, fmt.Errorf(\"failed to unregister metric: %v,\", \"dns_queries_total\"))\n\t}\n\tif !registry.Unregister(h.responses) {\n\t\terrs = errors.Join(errs, fmt.Errorf(\"failed to unregister metric: %v,\", \"dns_responses_total\"))\n\t}\n\tif !registry.Unregister(h.responseTypes) {\n\t\terrs = errors.Join(errs, fmt.Errorf(\"failed to unregister metric: %v,\", \"dns_response_types_total\"))\n\t}\n\treturn errs\n}\n\nfunc (h *dnsHandler) HandleConfigurationUpdate(cfg *api.MetricConfig) error {\n\treturn h.SetFilters(cfg)\n}\n\nfunc (h *dnsHandler) SetFilters(cfg *api.MetricConfig) error {\n\tvar err error\n\th.AllowList, err = filters.BuildFilterList(context.Background(), cfg.IncludeFilters, filters.DefaultFilters(slog.Default()))\n\tif err != nil {\n\t\treturn err\n\t}\n\th.DenyList, err = filters.BuildFilterList(context.Background(), cfg.ExcludeFilters, filters.DefaultFilters(slog.Default()))\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/hubble/metrics/dns/handler.go#L162-L198","documentation":"Same failure mode as 2927/2928 but for the dns_response_types_total collector: registry.Unregister(h.responseTypes) returned false during Deinit, so the bucketed response-type histogram was absent from the registry. The error is joined into Deinit's aggregate error.","triggerScenarios":"Deinit when h.responseTypes is not registered in the supplied registry — no prior successful Init, double Deinit, or registry mismatch.","commonSituations":"Handler teardown during dynamic metric reconfiguration where the collector was never added; tests constructing a handler manually and calling Deinit on an empty registry.","solutions":["Call Init (and SetFilters) successfully on this registry before Deinit","Pass the same registry instance used during registration","Ignore or tolerate false Unregister returns in tests if intentional"],"exampleFix":"// before\nh := newDNSHandler(...)\nh.Deinit(registry) // never Init'ed\n// after\nh.Init(registry)\n// ...\nh.Deinit(registry)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func canDeinit(h *dnsHandler, reg *prometheus.Registry) bool {\n    return h != nil && h.responseTypes != nil && reg != nil\n}","tryCatchPattern":"if err := h.Deinit(reg); err != nil {\n    logger.Warn(\"dns deinit incomplete\", \"err\", err)\n}","preventionTips":["Call Init before Deinit in tests and production reconfiguration","Keep Init/Deinit on the same goroutine or properly synchronized","Treat joined unregister errors as warnings and log, not crash"],"tags":["hubble","metrics","prometheus","lifecycle"],"backgroundTag":"metric-unregister-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}