cilium/cilium · warning

failed to unregister metric: tcp_flags_total,

Error message

failed to unregister metric: tcp_flags_total,

What it means

tcpHandler.Deinit returns this error when registry.Unregister(h.tcpFlags) returns false, meaning tcp_flags_total could not be removed from the registry because it is not registered there (or already removed).

Source

Thrown at pkg/hubble/metrics/tcp/handler.go:113

			h.tcpFlags.WithLabelValues(labels...).Inc()
		} else {
			labels[0] = "SYN"
			h.tcpFlags.WithLabelValues(labels...).Inc()
		}
	}

	if tcp.Flags.RST {
		labels[0] = "RST"
		h.tcpFlags.WithLabelValues(labels...).Inc()
	}

	return nil
}

func (h *tcpHandler) Deinit(registry *prometheus.Registry) error {
	var errs error
	if !registry.Unregister(h.tcpFlags) {
		errs = errors.Join(errs, fmt.Errorf("failed to unregister metric: %v,", "tcp_flags_total"))
	}
	return errs
}

func (h *tcpHandler) HandleConfigurationUpdate(cfg *api.MetricConfig) error {
	return h.SetFilters(cfg)
}

func (h *tcpHandler) 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

  1. Ensure Init registered tcpFlags on the same registry before Deinit.
  2. Avoid calling Deinit more than once per handler instance.
  3. Use one shared *prometheus.Registry for the handler's full lifecycle.

Example fix

// before
h.Deinit(reg)
h.Deinit(reg)
// after
if err := h.Deinit(reg); err != nil { return err } // once per handler
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm tcpFlags registered on registry before teardown

Try / catch

if err := h.Deinit(registry); err != nil {
    log.WithError(err).Warn("tcp_flags_total unregister failed")
}

Prevention

When it happens

Trigger: Calling Deinit with a registry lacking the tcp_flags_total collector — double Deinit, missing Init, or registry instance mismatch.

Common situations: Hubble shutdown paths, repeated config reloads triggering init/deinit cycles, test setups without registration.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/0ef096afaecd6871. Report an issue: GitHub.