{"record":{"id":"72c3d115f197225b","repo":"grpc/grpc-go","slug":"error-unmarshalling-xds-lb-policy-v","errorCode":null,"errorMessage":"error unmarshalling xDS LB Policy: %v","messagePattern":"error unmarshalling xDS LB Policy: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/balancer/cdsbalancer/cdsbalancer.go","lineNumber":256,"sourceCode":"\t\tp := b.updatePriorityConfig(clusterName, &clusterConfig)\n\t\tnewPriorities = append(newPriorities, p)\n\tcase xdsresource.ClusterTypeAggregate:\n\t\tfor _, leaf := range clusterConfig.AggregateConfig.LeafClusters {\n\t\t\tleafCluster := b.clusterConfigs[leaf]\n\t\t\t// Update priority config for leaf clusters.\n\t\t\tp := b.updatePriorityConfig(leaf, &leafCluster.Config)\n\t\t\tnewPriorities = append(newPriorities, p)\n\t\t}\n\t}\n\tb.priorities = newPriorities\n\n\tif err := b.updateOutlierDetection(); err != nil {\n\t\treturn b.annotateErrorWithNodeID(fmt.Errorf(\"failed to correctly update Outlier Detection config %v\", err))\n\t}\n\n\t// The LB policy is configured by the root cluster.\n\tif err := json.Unmarshal(clusterConfig.Cluster.LBPolicy, &b.xdsLBPolicy); err != nil {\n\t\treturn b.annotateErrorWithNodeID(fmt.Errorf(\"error unmarshalling xDS LB Policy: %v\", err))\n\t}\n\tif err := b.updateChildConfig(); err != nil {\n\t\treturn b.annotateErrorWithNodeID(err)\n\t}\n\treturn nil\n}\n\n// updateChildConfig builds child policy configuration using endpoint addresses\n// returned from the XDSConfig and child policy configuration.\n//\n// A child policy is created if one doesn't already exist. The newly built\n// configuration is then pushed to the child policy.\nfunc (b *cdsBalancer) updateChildConfig() error {\n\tif b.childLB == nil {\n\t\tchildLB, err := newChildBalancer(b.cc, b.bOpts)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create child policy of type %s: %v\", priority.Name, err)\n\t\t}","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/xds/balancer/cdsbalancer/cdsbalancer.go#L238-L274","documentation":"The CDS balancer unmarshals the cluster resource's LBPolicy field (raw JSON from the management server) into an internal BalancerConfig struct. This error fires when that JSON is malformed or contains unexpected field types. The LBPolicy determines the locality-picking and endpoint-picking strategy for the cluster's endpoints.","triggerScenarios":"Triggered in handleClusterUpdate() when json.Unmarshal(clusterConfig.Cluster.LBPolicy, &b.xdsLBPolicy) fails. The LBPolicy bytes come directly from the CDS resource sent by the management server (Envoy/Istio/Traffic Director).","commonSituations":"The management server sends an LB policy that uses fields or nesting not understood by the current grpc-go version; the cluster resource on the server has a corrupt or manually-edited LB policy; a protobuf-to-JSON serialization bug on the server side produces invalid JSON for the LB policy field.","solutions":["Inspect the raw LBPolicy JSON from the cluster resource (enable GRPC_GO_LOG_SEVERITY=info to see the received cluster config)","Verify the management server's cluster configuration for the LB policy field is valid JSON matching the expected schema","Upgrade grpc-go to a version compatible with the LB policy format your management server sends","Check the management server's configuration for the specific cluster for typos or schema violations in the LB policy"],"exampleFix":"// before: LB policy with invalid JSON from the server\n{\"lbPolicy\": \"weighted_round_robin\"}  // string instead of object\n// after: correct LB policy object\n{\"lbPolicy\": [{\"weighted_round_robin\": {\"enableOobLoadReport\": {}}}]}","handlingStrategy":"validation","validationCode":"// Validate LB policy JSON structure before expecting the balancer to handle it\n// This is done by the xDS client; for management server validation:\n// Test cluster resources against the expected LB policy JSON schema\nfunc validateLBPolicyJSON(raw []byte) error {\n    var dummy interface{}\n    return json.Unmarshal(raw, &dummy) // at minimum, must be valid JSON\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate management server cluster resources for LB policy field validity","Test xDS resource updates in a staging environment before production","Keep grpc-go and management server protocol versions compatible","Monitor xDS NACKs from the management server which indicate config validation issues"],"tags":["xds","cds","lb-policy","json","config"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}