cilium/cilium · error

failed to validate Cluster %q (%w): %s

Error message

failed to validate Cluster %q (%w): %s

What it means

When validation is enabled, ParseResources runs the ptypes Validate() on the fully qualified envoy Cluster and wraps any failure in this error, appending the cluster's string form for debugging. It means the cluster proto is structurally invalid per Envoy's proto constraints (missing required fields, invalid values), even though the name checks passed.

Source

Thrown at pkg/ciliumenvoyconfig/cec_resource_parser.go:401

			}

			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)
			}
			// Check that a Cluster name is provided
			if endpoints.ClusterName == "" {
				return xds.Resources{}, fmt.Errorf("unspecified ClusterLoadAssignment cluster_name")
			}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Read the wrapped inner error and the cluster dump in the message to find the offending field, then fix the cluster config in the CiliumEnvoyConfig
  2. Run the cluster proto through the same Validate() in a unit test locally to iterate quickly
  3. Compare against a known-good generated cluster from cilium (cilium-dbg bgp/envoy output) and align fields

Example fix

// before
cluster := &envoy_config_cluster.Cluster{
    Name: "svc",
    ClusterDiscoveryType: envoy_config_cluster.Cluster_STATIC, // static but no load_assignment
}
// after
cluster := &envoy_config_cluster.Cluster{
    Name:                 "svc",
    ClusterDiscoveryType: envoy_config_cluster.Cluster_STATIC,
    LoadAssignment: &envoy_config_endpoint.ClusterLoadAssignment{
        ClusterName: "svc",
        Endpoints:   []*envoy_config_endpoint.LocalityLbEndpoints{{LbEndpoints: []*envoy_config_endpoint.LbEndpoint{...}}},
    },
}
Defensive patterns

Strategy: validation

Validate before calling

for _, res := range cecResources {
    if res.GetTypeUrl() == envoy.ClusterTypeURL {
        var c envoy_config_cluster.Cluster
        if err := res.UnmarshalTo(&c); err != nil { return err }
        if err := c.Validate(); err != nil {
            return fmt.Errorf("invalid cluster %q: %w", c.GetName(), err)
        }
    }
}

Try / catch

res, err := parser.ParseResources(ns, name, anyResources, true, knobs)
if err != nil {
    if strings.Contains(err.Error(), "failed to validate Cluster") {
        // surface the wrapped cause and cluster dump to the CEC status
        return fmt.Errorf("CEC %s/%s rejected: %w", ns, name, err)
    }
    return err
}

Prevention

When it happens

Trigger: ParseResources called with validate=true and a Cluster whose contents violate Envoy proto validation — e.g. unknown/invalid cluster type, bad connect_timeout, invalid TLS transport_socket config, or address/port mismatches. The underlying err (via %w) names the exact field.

Common situations: Hand-written Envoy cluster configs with typos or unsupported values; a Cilium upgrade tightening envoy validation rules; mixing fields not allowed together (e.g. static vs EDS config); filling in an invalid TransportSocket name.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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