grpc/grpc-go · error
failed to build child policy config
Error message
failed to build child policy config: %v
What it means
Returned by updateChildConfig (line 280) when buildPriorityConfigJSON (configbuilder.go:96) fails. buildPriorityConfigJSON delegates to buildPriorityConfig (line 108) which iterates over priorities and calls buildClusterImplConfigForEDS or buildClusterImplConfigForDNS. The inner error is propagated from errors 357 (failed to build priority config) or 358 (failed to marshal).
Solutions
- Inspect the wrapped %v error to determine whether it came from buildPriorityConfig (error 357) or json.Marshal (error 358).
- Check the cluster resource's locality and endpoint data for unusual values (extremely large weights, unexpected endpoint types).
- Report the issue to grpc-go with the cluster resource details if the data appears valid but the builder still fails.
- Ensure you are on the latest grpc-go patch release in case this is a fixed bug.
Defensive patterns
Strategy: try-catch
Try / catch
// This is an internal error from the config builder. It surfaces as
// TRANSIENT_FAILURE. Unwrap for diagnostics:
err := <-errChan // from your monitoring
var inner error
if errors.As(err, &inner) {
log.Printf("config builder failed: %v", inner)
// check cluster resource data for anomalies
} Prevention
- Keep grpc-go updated to the latest patch release.
- Monitor xDS resource validity on the management server side.
- Log cluster resource details when TRANSIENT_FAILURE occurs for post-mortem analysis.
When it happens
Trigger: During a cluster config update, the CDS balancer builds the priority/cluster_impl/outlier-detection/xdsLBPolicy child config tree (see the ASCII diagram in configbuilder.go lines 84-95). If any locality-to-cluster_impl conversion fails (e.g., in priorityLocalitiesToClusterImpl) or the final JSON marshal fails, this error surfaces.
Common situations: An internal invariant violation in the config builder (priorityLocalitiesToClusterImpl returns an error). This is rare since the input comes from already-validated xDS resources. Could be triggered by an edge case in endpoint weight computation or locality grouping that the xDS client did not anticipate.
Related errors
- failed to build priority config
- did not find the cluster
- error unmarshalling xDS LB Policy
- failed to correctly update Outlier Detection config
- failed to create child policy of type
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/6106fa22375a584f.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/balancer/cdsbalancer/cdsbalancer.go:280
}
// 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)
}
b.childLB = childLB
}
childCfgBytes, endpoints, err := buildPriorityConfigJSON(b.priorities, &b.xdsLBPolicy)
if err != nil {
return fmt.Errorf("failed to build child policy config: %v", err)
}
childCfg, err := b.childConfigParser.ParseConfig(childCfgBytes)
if err != nil {
return fmt.Errorf("failed to parse child policy config. This should never happen because the config was generated: %v", err)
}
if b.logger.V(2) {
b.logger.Infof("Built child policy config: %s", pretty.ToJSON(childCfg))
}
for i := range endpoints {
for j := range endpoints[i].Addresses {
addr := endpoints[i].Addresses[j]
addr.BalancerAttributes = endpoints[i].Attributes
// BalancerAttributes are used for the following:
// * Authority Override.
// * grpc.lb.backend_service metric label propagation.
// See https://github.com/grpc/grpc-go/issues/6472
endpoints[i].Addresses[j] = addrView on GitHub (pinned to 0c51461d27)