grpc/grpc-go · error
failed to create child policy of type %s: %v
Error message
failed to create child policy of type %s: %v
What it means
The CDS balancer creates a child balancer (of type priority) when none exists, via newChildBalancer(). This error wraps any failure from that creation. The priority balancer is a core gRPC balancer that manages failover across priority levels within a cluster.
Source
Thrown at internal/xds/balancer/cdsbalancer/cdsbalancer.go:273
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)
}
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 {View on GitHub (pinned to 03255a9237)
Solutions
- This error indicates an internal gRPC issue — ensure you are using a stable grpc-go release, not a custom build that might exclude the priority balancer
- If using a custom balancer registration mechanism, verify the priority balancer ("priority_experimental") is registered
- Report as a bug if it occurs on a standard grpc-go build with no custom balancer modifications
- Check for memory or resource exhaustion that might cause balancer.Build() to fail
Defensive patterns
Strategy: fallback
Validate before calling
// No pre-validation possible — this is an internal balancer creation error // Ensure the priority balancer is registered by checking the registry
Try / catch
// The channel enters TRANSIENT_FAILURE; monitor connectivity state
if conn.GetState() == connectivity.TransientFailure {
// this is an internal error; report to grpc-go maintainers
} Prevention
- Use standard grpc-go builds without stripping balancer registrations
- Keep grpc-go up to date
- Monitor channel connectivity states and alert on persistent TRANSIENT_FAILURE
- Report internal balancer creation errors as bugs
When it happens
Trigger: Triggered in updateChildConfig() when b.childLB is nil and newChildBalancer(b.cc, b.bOpts) returns an error. The child balancer is always a priority balancer; failure would come from the priority balancer's Build() method.
Common situations: The priority balancer is not registered in the balancer registry (very unlikely in standard builds); a custom build that excludes or overrides core balancer registration; a nil ClientConn or broken BuildOptions passed internally (indicates a gRPC internal bug).
Related errors
- no priority is provided, all priorities are removed
- xds: unable to unmarshal lbconfig: %s, error: %v
- failed to correctly update Outlier Detection config %v
- failed to build child policy config: %v
- failed to build priority config: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/316bd5c908cbfedc.
Report an issue: GitHub.