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

  1. 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
  2. If using a custom balancer registration mechanism, verify the priority balancer ("priority_experimental") is registered
  3. Report as a bug if it occurs on a standard grpc-go build with no custom balancer modifications
  4. 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

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


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/316bd5c908cbfedc. Report an issue: GitHub.