{"record":{"id":"64a329c02d153fc7","repo":"grpc/grpc-java","slug":"failed-to-parse-lb-config-for-cluster-cluster","errorCode":null,"errorMessage":"Failed to parse lb config for cluster '\" + cluster.getName() + \"': \" + configOrError.getError()","messagePattern":"Failed to parse lb config for cluster '\" \\+ cluster\\.getName\\(\\) \\+ \"': \" \\+ configOrError\\.getError\\(\\)","errorType":"validation","errorClass":"ResourceInvalidException","httpStatus":null,"severity":"error","filePath":"xds/src/main/java/io/grpc/xds/XdsClusterResource.java","lineNumber":171,"sourceCode":"        break;\n      case CLUSTERDISCOVERYTYPE_NOT_SET:\n      default:\n        throw new ResourceInvalidException(\n            \"Cluster \" + cluster.getName() + \": unspecified cluster discovery type\");\n    }\n    if (structOrError.getErrorDetail() != null) {\n      throw new ResourceInvalidException(structOrError.getErrorDetail());\n    }\n    CdsUpdate.Builder updateBuilder = structOrError.getStruct();\n\n    ImmutableMap<String, ?> lbPolicyConfig = LoadBalancerConfigFactory.newConfig(cluster,\n        enableLeastRequest);\n\n    NameResolver.ConfigOrError configOrError\n        = GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(\n            ImmutableList.of(lbPolicyConfig), loadBalancerRegistry);\n    if (configOrError.getError() != null) {\n      throw new ResourceInvalidException(\n          \"Failed to parse lb config for cluster '\" + cluster.getName() + \"': \"\n          + configOrError.getError());\n    }\n\n    updateBuilder.lbPolicyConfig(configOrError.getConfig(), lbPolicyConfig);\n    updateBuilder.filterMetadata(\n        ImmutableMap.copyOf(cluster.getMetadata().getFilterMetadataMap()));\n\n    try {\n      MetadataRegistry registry = MetadataRegistry.getInstance();\n      ImmutableMap<String, Object> parsedFilterMetadata =\n          registry.parseMetadata(cluster.getMetadata());\n      updateBuilder.parsedMetadata(parsedFilterMetadata);\n    } catch (ResourceInvalidException e) {\n      throw new ResourceInvalidException(\n          \"Failed to parse xDS filter metadata for cluster '\" + cluster.getName() + \"': \"\n              + e.getMessage(), e);\n    }","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/xds/src/main/java/io/grpc/xds/XdsClusterResource.java#L153-L189","documentation":"After the cluster's lb policy config map is built via LoadBalancerConfigFactory, processCluster runs it through GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig. If that returns an error, the load-balancing policy configuration for the cluster is invalid/unusable by the local gRPC LB registry and the message is wrapped in a ResourceInvalidException.","triggerScenarios":"A Cluster advertises an lb policy (round_robin, least_request, ring_hash, etc.) whose generated config fails local parsing — e.g. unsupported child policy name, malformed policy JSON, or a policy not registered in the local LoadBalancer registry.","commonSituations":"Control plane sends custom or newer LB policies the client doesn't support; least_request/ring_hash config fields from a newer Envoy API than the client's protobuf version; typo'd policy name in cluster config.","solutions":["Align the cluster's lb policy with a policy the client supports (e.g. round_robin or ring_hash with valid fields)","Upgrade grpc-xds / generated Envoy protos to a version that recognizes the policy and fields sent by the control plane","Register the missing custom LoadBalancer provider on the client if a custom policy is intended"],"exampleFix":"// before\n{\"leastRequest\": {\"choiceCount\": -1}}\n// after\n{\"leastRequest\": {\"choiceCount\": 2}}","handlingStrategy":"validation","validationCode":"NameResolver.ConfigOrError check = GracefulSwitchLoadBalancer.parseLoadBalancingPolicyConfig(\n    ImmutableList.of(lbPolicyConfig), loadBalancerRegistry);\nif (check.getError() != null) {\n  throw new IllegalArgumentException(\"Invalid lb config: \" + check.getError());\n}","typeGuard":null,"tryCatchPattern":"try {\n  cdsUpdate = xdsClusterResource.parseResource(args);\n} catch (ResourceInvalidException e) {\n  if (e.getMessage().contains(\"Failed to parse lb config\")) {\n    // fall back to round_robin or fix control-plane policy\n  }\n}","preventionTips":["Only advertise LB policies registered on the client","Keep Envoy proto versions in sync with the control plane's features","Pre-parse lb policy configs with the same registry as the client in CI"],"tags":["grpc","xds","load-balancing","config-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}