{"record":{"id":"258d7f1649808585","repo":"cilium/cilium","slug":"plugin-s-conflicts-with-plugin-s","errorCode":null,"errorMessage":"plugin %s conflicts with plugin %s","messagePattern":"plugin (.+?) conflicts with plugin (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/hubble/metrics/api/registry.go","lineNumber":85,"sourceCode":"\treturn InitHandlers(logger, registry, &enabledHandlers)\n}\n\nfunc (r *Registry) ValidateAndCreateHandler(metricsConfig *MetricConfig, metricNames *map[string]*MetricConfig) (*NamedHandler, error) {\n\tr.mutex.Lock()\n\tdefer r.mutex.Unlock()\n\treturn r.validateAndCreateHandlerLocked(metricsConfig, metricNames)\n}\n\nfunc (r *Registry) validateAndCreateHandlerLocked(metricsConfig *MetricConfig, metricNames *map[string]*MetricConfig) (*NamedHandler, error) {\n\tplugin, ok := r.handlers[metricsConfig.Name]\n\tif !ok {\n\t\treturn nil, &errMetricNotExist{metricsConfig.Name}\n\t}\n\n\tif cp, ok := plugin.(PluginConflicts); ok {\n\t\tfor _, conflict := range cp.ConflictingPlugins() {\n\t\t\tif _, conflictExists := (*metricNames)[conflict]; conflictExists {\n\t\t\t\treturn nil, fmt.Errorf(\"plugin %s conflicts with plugin %s\", metricsConfig.Name, conflict)\n\t\t\t}\n\t\t}\n\t}\n\n\th := NamedHandler{\n\t\tName:         metricsConfig.Name,\n\t\tHandler:      plugin.NewHandler(),\n\t\tMetricConfig: metricsConfig,\n\t}\n\n\treturn &h, nil\n}\n\ntype errMetricNotExist struct {\n\tname string\n}\n\nfunc (e *errMetricNotExist) Error() string {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/hubble/metrics/api/registry.go#L67-L103","documentation":"validateAndCreateHandlerLocked checks plugin-declared conflicts before instantiating a metric handler. If a plugin implements PluginConflicts and lists another plugin that is already registered under the same metrics registry, registration is refused. This prevents two mutually exclusive metric handlers (e.g. two flow metrics with overlapping Prometheus names) from being enabled simultaneously.","triggerScenarios":"Configuring two conflicting metrics at once, e.g. `metrics: [\"flow\",\"flow:sourceContext=workload\"]` variants, or any pair where one plugin's ConflictingPlugins() includes the other's registered name in (*metricNames).","commonSituations":"Appending a new metric to the hubble-metrics list without realizing it conflicts with an existing one (e.g. duplicate flow metrics, dns + a conflicting variant); merging helm values that each add a metric.","solutions":["Remove one of the two conflicting metric configurations from the hubble-metrics list","Reconfigure one metric with options so it no longer declares the conflict (e.g. use distinct sourceContext settings)","Check the plugin's ConflictingPlugins() implementation in pkg/hubble/metrics to see exactly which names clash"],"exampleFix":"// before\nmetrics: [\"flow\", \"flow:sourceContext=workload\"]\n// after\nmetrics: [\"flow:sourceContext=res-bytes,destinationContext=workload\"]","handlingStrategy":"validation","validationCode":"// Deduplicate metric names before configuring\nseen := map[string]bool{}\nfor _, m := range strings.Fields(metricsConfig) {\n    name := strings.SplitN(m, \":\", 2)[0]\n    if seen[name] { return fmt.Errorf(\"duplicate/conflicting metric: %s\", name) }\n    seen[name] = true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one entry per metric plugin in hubble-metrics","Review ConflictingPlugins() of each enabled plugin before combining metrics","Merge helm values carefully to avoid duplicated flow entries"],"tags":["hubble","metrics","configuration","plugin-conflict"],"backgroundTag":"duplicate-registration-conflict","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}