{"record":{"id":"d9774b31424dc408","repo":"grpc/grpc-go","slug":"did-not-find-the-cluster-q-in-xdsconfig","errorCode":null,"errorMessage":"did not find the cluster %q in XDSConfig","messagePattern":"did not find the cluster %q in XDSConfig","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/balancer/cdsbalancer/cdsbalancer.go","lineNumber":220,"sourceCode":"\n\t// If the cluster is dynamic and we dont have a subscription yet, create\n\t// one.\n\tif b.lbCfg.IsDynamic && !b.isSubscribed {\n\t\tb.unsubscribe = b.clusterSubscriber.SubscribeToCluster(clusterName)\n\t\tb.isSubscribed = true\n\t\treturn nil\n\t}\n\n\tclusterUpdate, ok := b.clusterConfigs[clusterName]\n\tif !ok {\n\t\t// If the cluster is missing from the config, check if it is dynamic.\n\t\t// For dynamic clusters, the xDS config may be updated before the\n\t\t// corresponding cluster resource is received. This should never occur\n\t\t// for static clusters.\n\t\tif b.lbCfg.IsDynamic {\n\t\t\treturn nil\n\t\t}\n\t\treturn b.annotateErrorWithNodeID(fmt.Errorf(\"did not find the cluster %q in XDSConfig\", clusterName))\n\t}\n\t// If the cluster resource has an error, return the error.\n\tif clusterUpdate.Err != nil {\n\t\treturn clusterUpdate.Err\n\t}\n\treturn b.handleClusterUpdate()\n}\n\n// handleClusterUpdate handles a good XDSConfig update from the xDS resolver.\n// Builds the child policy config and pushes it down.\nfunc (b *cdsBalancer) handleClusterUpdate() error {\n\tclusterName := b.lbCfg.ClusterName\n\tclusterConfig := b.clusterConfigs[clusterName].Config\n\n\tvar newPriorities []*priorityConfig\n\tswitch clusterConfig.Cluster.ClusterType {\n\tcase xdsresource.ClusterTypeEDS, xdsresource.ClusterTypeLogicalDNS:\n\t\tp := b.updatePriorityConfig(clusterName, &clusterConfig)","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/balancer/cdsbalancer/cdsbalancer.go#L202-L238","documentation":"Returned by handleXDSConfigUpdate (line 220, wrapped via annotateErrorWithNodeID) when the cluster name from the LB config is not present in the XDSConfig.Clusters map (b.clusterConfigs). The code at lines 211-221 checks: for dynamic clusters an early return nil is allowed (the cluster resource may arrive later), but for static (non-dynamic) clusters the absence is a hard error. The error message is prefixed with the xDS node ID for diagnostics.","triggerScenarios":"A static CDS cluster (isDynamic=false) is referenced in the service config but the corresponding cluster resource was never received or processed by the xDS client. This happens when the management server's LDS/RDS/CDS resources are inconsistent — the route configuration references a cluster that the CDS response does not include.","commonSituations":"Management server misconfiguration: the route points to cluster 'A' but only cluster 'B' was sent in the CDS response. Ordering issue where LDS/RDS arrive but the CDS resource for the cluster is NACK'd or never delivered. Bootstrap configuration pointing to the wrong xDS server that serves incomplete resources. A cluster rename in the control plane that left the route stale.","solutions":["Check the xDS management server (Envoy, Istio, Traffic Director) configuration to confirm the cluster referenced by the route actually exists and is being sent via CDS.","Enable xDS debug logging (GRPC_GO_LOG_SEVERITY=info, GRPC_XDS_DEBUG=v) and inspect the CDS resources received — look for the cluster name in the response.","Verify the node ID in the bootstrap matches what the management server expects so it returns the correct resources for this client.","If using aggregate clusters, confirm all leaf clusters in the aggregate chain are delivered.","Check for CDS NACK errors in the logs — a NACK'd resource won't populate the config map even if it was sent."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before relying on a cluster, verify it exists in the xDS config\n// This is done at the xDS resolver level, but you can check resolver state:\nfunc validateClusterInState(rs resolver.State, clusterName string) error {\n    xdsCfg := xdsresource.XDSConfigFromResolverState(rs)\n    if xdsCfg == nil {\n        return fmt.Errorf(\"no xDS config in resolver state\")\n    }\n    if _, ok := xdsCfg.Clusters[clusterName]; !ok {\n        return fmt.Errorf(\"cluster %q not in xDS config\", clusterName)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// The CDS balancer returns this from UpdateClientConnState;\n// the channel enters TRANSIENT_FAILURE. Monitor connectivity state:\nconn.WaitForStateChange(ctx, connectivity.Ready)\nif conn.GetState() == connectivity.TransientFailure {\n    // check logs for 'did not find the cluster' error\n    // verify management server config\n}","preventionTips":["Ensure the management server's route configuration and CDS resources are consistent — every cluster referenced in a route must exist in CDS.","Use xDS debug logging to inspect received CDS resources during development.","Validate the bootstrap node ID matches what the management server expects."],"tags":["xds","cds","cluster","config","management-server"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}