{"record":{"id":"45a17ee9328462f1","repo":"cilium/cilium","slug":"duplicate-cluster-name-q","errorCode":null,"errorMessage":"duplicate Cluster name %q","messagePattern":"duplicate Cluster name %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/ciliumenvoyconfig/cec_resource_parser.go","lineNumber":395,"sourceCode":"\t\t\t\t\t// In ADS mode all inline xDS references must use the aggregated\n\t\t\t\t\t// stream. Gateway-generated CEC clusters may already carry a split\n\t\t\t\t\t// xDS source, so normalize only ADS mode and preserve the existing\n\t\t\t\t\t// behavior for legacy split xDS mode.\n\t\t\t\t\tcluster.EdsClusterConfig.EdsConfig = envoy.CiliumConfigSource(r.xdsMode)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif cluster.LoadAssignment != nil {\n\t\t\t\tqualifyEDSEndpoints(cecNamespace, cecName, cluster.LoadAssignment)\n\t\t\t}\n\n\t\t\tname := cluster.Name\n\t\t\tcluster.Name, _ = api.ResourceQualifiedName(cecNamespace, cecName, name)\n\n\t\t\t// Check for duplicate after the name has been qualified\n\t\t\tfor i := range resources.Clusters {\n\t\t\t\tif cluster.Name == resources.Clusters[i].Name {\n\t\t\t\t\treturn xds.Resources{}, fmt.Errorf(\"duplicate Cluster name %q\", cluster.Name)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif validate {\n\t\t\t\tif err := cluster.Validate(); err != nil {\n\t\t\t\t\treturn xds.Resources{}, fmt.Errorf(\"failed to validate Cluster %q (%w): %s\", cluster.Name, err, cluster.String())\n\t\t\t\t}\n\t\t\t}\n\t\t\tresources.Clusters[cluster.Name] = cluster\n\n\t\t\tr.logger.Debug(\"ParseResources: Parsed cluster\",\n\t\t\t\tlogfields.Name, name,\n\t\t\t\tlogfields.ResourceClusters, cluster)\n\n\t\tcase envoy.EndpointTypeURL:\n\t\t\tendpoints, ok := message.(*envoy_config_endpoint.ClusterLoadAssignment)\n\t\t\tif !ok {\n\t\t\t\treturn xds.Resources{}, fmt.Errorf(\"invalid type for Route: %T\", message)","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/ciliumenvoyconfig/cec_resource_parser.go#L377-L413","documentation":"ParseResources qualifies each Cluster name with the CEC namespace/name via api.ResourceQualifiedName and then rejects the resource list if two clusters resolve to the same qualified name. Envoy requires unique cluster names, so a duplicate causes the whole parse to fail with empty xds.Resources.","triggerScenarios":"ParseResources receives two Cluster-type Any messages that, after name qualification with <cecNamespace>/<cecName>, produce identical cluster.Name values — e.g. two cluster entries in the same CiliumEnvoyConfig with the same name (or empty names that qualify identically).","commonSituations":"Copy-pasting a cluster stanza in a CiliumEnvoyConfig YAML without renaming it; merging CEC configs and colliding names; accidental duplicate entries after a Helm template renders the same cluster twice; forgetting that names are namespaced so collisions occur within one CEC object.","solutions":["Rename one of the duplicate cluster entries in the CiliumEnvoyConfig so qualified names differ","List all 'clusters:' names in the CEC YAML and deduplicate before applying","If generating clusters in code, keep a set of already-used names and error out at generation time"],"exampleFix":"// before (two entries in CiliumEnvoyConfig)\nclusters:\n- name: backend\n  ...\n- name: backend\n  ...\n// after\nclusters:\n- name: backend\n  ...\n- name: backend-tls\n  ...","handlingStrategy":"validation","validationCode":"seen := map[string]bool{}\nfor _, res := range cecResources {\n    if res.GetTypeUrl() == envoy.ClusterTypeURL {\n        var c envoy_config_cluster.Cluster\n        if err := res.UnmarshalTo(&c); err != nil { return err }\n        q, _ := api.ResourceQualifiedName(ns, name, c.GetName())\n        if seen[q] { return fmt.Errorf(\"duplicate cluster %q\", q) }\n        seen[q] = true\n    }\n}","typeGuard":null,"tryCatchPattern":"res, err := parser.ParseResources(ns, name, anyResources, validate, knobs)\nif err != nil {\n    var dupErr string = \"duplicate Cluster name\"\n    if strings.Contains(err.Error(), dupErr) {\n        return fmt.Errorf(\"CEC %s/%s: %w — fix duplicate cluster names in the manifest\", ns, name, err)\n    }\n    return err\n}","preventionTips":["Keep cluster names unique within each CiliumEnvoyConfig","Deduplicate generated resource lists by qualified name before parsing","Review Helm/template output for duplicated cluster stanzas"],"tags":["cilium","envoy","xds","duplicate-resource"],"backgroundTag":"duplicate-resource-name","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}