cilium/cilium · error

duplicate Cluster name %q

Error message

duplicate Cluster name %q

What it means

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.

Source

Thrown at pkg/ciliumenvoyconfig/cec_resource_parser.go:395

					// In ADS mode all inline xDS references must use the aggregated
					// stream. Gateway-generated CEC clusters may already carry a split
					// xDS source, so normalize only ADS mode and preserve the existing
					// behavior for legacy split xDS mode.
					cluster.EdsClusterConfig.EdsConfig = envoy.CiliumConfigSource(r.xdsMode)
				}
			}

			if cluster.LoadAssignment != nil {
				qualifyEDSEndpoints(cecNamespace, cecName, cluster.LoadAssignment)
			}

			name := cluster.Name
			cluster.Name, _ = api.ResourceQualifiedName(cecNamespace, cecName, name)

			// Check for duplicate after the name has been qualified
			for i := range resources.Clusters {
				if cluster.Name == resources.Clusters[i].Name {
					return xds.Resources{}, fmt.Errorf("duplicate Cluster name %q", cluster.Name)
				}
			}

			if validate {
				if err := cluster.Validate(); err != nil {
					return xds.Resources{}, fmt.Errorf("failed to validate Cluster %q (%w): %s", cluster.Name, err, cluster.String())
				}
			}
			resources.Clusters[cluster.Name] = cluster

			r.logger.Debug("ParseResources: Parsed cluster",
				logfields.Name, name,
				logfields.ResourceClusters, cluster)

		case envoy.EndpointTypeURL:
			endpoints, ok := message.(*envoy_config_endpoint.ClusterLoadAssignment)
			if !ok {
				return xds.Resources{}, fmt.Errorf("invalid type for Route: %T", message)

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Rename one of the duplicate cluster entries in the CiliumEnvoyConfig so qualified names differ
  2. List all 'clusters:' names in the CEC YAML and deduplicate before applying
  3. If generating clusters in code, keep a set of already-used names and error out at generation time

Example fix

// before (two entries in CiliumEnvoyConfig)
clusters:
- name: backend
  ...
- name: backend
  ...
// after
clusters:
- name: backend
  ...
- name: backend-tls
  ...
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, res := range cecResources {
    if res.GetTypeUrl() == envoy.ClusterTypeURL {
        var c envoy_config_cluster.Cluster
        if err := res.UnmarshalTo(&c); err != nil { return err }
        q, _ := api.ResourceQualifiedName(ns, name, c.GetName())
        if seen[q] { return fmt.Errorf("duplicate cluster %q", q) }
        seen[q] = true
    }
}

Try / catch

res, err := parser.ParseResources(ns, name, anyResources, validate, knobs)
if err != nil {
    var dupErr string = "duplicate Cluster name"
    if strings.Contains(err.Error(), dupErr) {
        return fmt.Errorf("CEC %s/%s: %w — fix duplicate cluster names in the manifest", ns, name, err)
    }
    return err
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


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