grpc/grpc-go · error
error unmarshalling xDS LB Policy: %v
Error message
error unmarshalling xDS LB Policy: %v
What it means
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.
Source
Thrown at internal/xds/balancer/cdsbalancer/cdsbalancer.go:256
p := b.updatePriorityConfig(clusterName, &clusterConfig)
newPriorities = append(newPriorities, p)
case xdsresource.ClusterTypeAggregate:
for _, leaf := range clusterConfig.AggregateConfig.LeafClusters {
leafCluster := b.clusterConfigs[leaf]
// Update priority config for leaf clusters.
p := b.updatePriorityConfig(leaf, &leafCluster.Config)
newPriorities = append(newPriorities, p)
}
}
b.priorities = newPriorities
if err := b.updateOutlierDetection(); err != nil {
return b.annotateErrorWithNodeID(fmt.Errorf("failed to correctly update Outlier Detection config %v", err))
}
// The LB policy is configured by the root cluster.
if err := json.Unmarshal(clusterConfig.Cluster.LBPolicy, &b.xdsLBPolicy); err != nil {
return b.annotateErrorWithNodeID(fmt.Errorf("error unmarshalling xDS LB Policy: %v", err))
}
if err := b.updateChildConfig(); err != nil {
return b.annotateErrorWithNodeID(err)
}
return nil
}
// updateChildConfig builds child policy configuration using endpoint addresses
// returned from the XDSConfig and child policy configuration.
//
// A child policy is created if one doesn't already exist. The newly built
// configuration is then pushed to the child policy.
func (b *cdsBalancer) updateChildConfig() error {
if b.childLB == nil {
childLB, err := newChildBalancer(b.cc, b.bOpts)
if err != nil {
return fmt.Errorf("failed to create child policy of type %s: %v", priority.Name, err)
}View on GitHub (pinned to 03255a9237)
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
Example fix
// before: LB policy with invalid JSON from the server
{"lbPolicy": "weighted_round_robin"} // string instead of object
// after: correct LB policy object
{"lbPolicy": [{"weighted_round_robin": {"enableOobLoadReport": {}}}]} Defensive patterns
Strategy: validation
Validate before calling
// Validate LB policy JSON structure before expecting the balancer to handle it
// This is done by the xDS client; for management server validation:
// Test cluster resources against the expected LB policy JSON schema
func validateLBPolicyJSON(raw []byte) error {
var dummy interface{}
return json.Unmarshal(raw, &dummy) // at minimum, must be valid JSON
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- xds: unable to unmarshal lbconfig: %s, error: %v
- error parsing Outlier Detection config %v: %v
- UpstreamTlsContext in CDS response does not contain a Common
- did not find the cluster %q in XDSConfig
- failed to correctly update Outlier Detection config %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/72c3d115f197225b.
Report an issue: GitHub.