cilium/cilium · warning
failed to unregister metric: dns_response_types_total,
Error message
failed to unregister metric: dns_response_types_total,
What it means
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.
Source
Thrown at pkg/hubble/metrics/dns/handler.go:180
newLabels = append(newLabels, dns.Query)
}
h.responseTypes.WithLabelValues(newLabels...).Inc()
}
}
return nil
}
func (h *dnsHandler) Deinit(registry *prometheus.Registry) error {
var errs error
if !registry.Unregister(h.queries) {
errs = errors.Join(errs, fmt.Errorf("failed to unregister metric: %v,", "dns_queries_total"))
}
if !registry.Unregister(h.responses) {
errs = errors.Join(errs, fmt.Errorf("failed to unregister metric: %v,", "dns_responses_total"))
}
if !registry.Unregister(h.responseTypes) {
errs = errors.Join(errs, fmt.Errorf("failed to unregister metric: %v,", "dns_response_types_total"))
}
return errs
}
func (h *dnsHandler) HandleConfigurationUpdate(cfg *api.MetricConfig) error {
return h.SetFilters(cfg)
}
func (h *dnsHandler) SetFilters(cfg *api.MetricConfig) error {
var err error
h.AllowList, err = filters.BuildFilterList(context.Background(), cfg.IncludeFilters, filters.DefaultFilters(slog.Default()))
if err != nil {
return err
}
h.DenyList, err = filters.BuildFilterList(context.Background(), cfg.ExcludeFilters, filters.DefaultFilters(slog.Default()))
if err != nil {
return err
}View on GitHub (pinned to ac7b90affa)
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
Example fix
// before h := newDNSHandler(...) h.Deinit(registry) // never Init'ed // after h.Init(registry) // ... h.Deinit(registry)
Defensive patterns
Strategy: type-guard
Type guard
func canDeinit(h *dnsHandler, reg *prometheus.Registry) bool {
return h != nil && h.responseTypes != nil && reg != nil
} Try / catch
if err := h.Deinit(reg); err != nil {
logger.Warn("dns deinit incomplete", "err", err)
} Prevention
- 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
When it happens
Trigger: Deinit when h.responseTypes is not registered in the supplied registry — no prior successful Init, double Deinit, or registry mismatch.
Common situations: Handler teardown during dynamic metric reconfiguration where the collector was never added; tests constructing a handler manually and calling Deinit on an empty registry.
Related errors
- failed to unregister metric: dns_queries_total,
- failed to unregister metric: dns_responses_total,
- failed to unregister metric: drop_total,
- failed to unregister metric: flows_processed_total,
- failed to unregister metric: flows_to_world_total,
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/1cd9974277fa8fb9.
Report an issue: GitHub.