grpc/grpc-go · error

child policy %q not registered

Error message

child policy %q not registered

What it means

The cluster_impl balancer looks up the child policy name from its config in the global balancer registry and finds nothing. The child policy is the locality-picking/endpoint-picking balancer (e.g., round_robin, weighted_round_robin) that runs beneath cluster_impl. This error means the specified policy name is unknown to gRPC's balancer registry.

Source

Thrown at internal/xds/balancer/clusterimpl/clusterimpl.go:412

	defer clientConnUpdateHook()

	b.mu.Lock()
	b.inhibitPickerUpdates = true
	b.mu.Unlock()
	if b.logger.V(2) {
		b.logger.Infof("Received configuration: %s", pretty.ToJSON(s.BalancerConfig))
	}
	newConfig, ok := s.BalancerConfig.(*LBConfig)
	if !ok {
		return fmt.Errorf("unexpected balancer config with type: %T", s.BalancerConfig)
	}

	// Need to check for potential errors at the beginning of this function, so
	// that on errors, we reject the whole config, instead of applying part of
	// it.
	bb := balancer.Get(newConfig.ChildPolicy.Name)
	if bb == nil {
		return fmt.Errorf("child policy %q not registered", newConfig.ChildPolicy.Name)
	}

	if b.xdsClient == nil {
		c := xdsclient.FromResolverState(s.ResolverState)
		if c == nil {
			return balancer.ErrBadResolverState
		}
		b.xdsClient = c
	}

	xdsConfig := xdsresource.XDSConfigFromResolverState(s.ResolverState)
	if xdsConfig == nil {
		b.logger.Warningf("Received balancer config with no xDS config")
		return balancer.ErrBadResolverState
	}
	clusterCfg := xdsConfig.Clusters[newConfig.Cluster]
	clusterUpdate := clusterCfg.Config.Cluster
	if err := b.handleSecurityConfig(clusterUpdate.SecurityCfg); err != nil {

View on GitHub (pinned to 03255a9237)

Solutions

  1. Check the child policy name in the error message and verify it is a supported gRPC xDS LB policy (round_robin, weighted_round_robin, ring_hash_experimental, least_request_experimental)
  2. Import the required balancer package (e.g., import _ "google.golang.org/grpc/balancer/weightedroundrobin")
  3. Upgrade grpc-go to a version that supports the requested LB policy
  4. Reconfigure the management server to use an LB policy supported by your client version

Example fix

// before: ring_hash not imported, management server requests it
import (
    _ "google.golang.org/grpc/xds"
)
// after: import ring_hash balancer
import (
    _ "google.golang.org/grpc/xds"
    _ "google.golang.org/grpc/balancer/ringhash"
)
Defensive patterns

Strategy: validation

Validate before calling

// Verify all child policies are registered before starting xDS
func areChildPoliciesRegistered(policyNames []string) error {
    for _, name := range policyNames {
        if balancer.Get(name) == nil {
            return fmt.Errorf("child policy %q is not registered; import its package", name)
        }
    }
    return nil
}
// Usage: check policies used by your management server's cluster configs

Try / catch

// The channel enters TRANSIENT_FAILURE for the affected cluster
if conn.GetState() == connectivity.TransientFailure {
    // check logs for 'child policy X not registered'
    // import the missing balancer package
}

Prevention

When it happens

Trigger: Triggered in cluster_impl's UpdateClientConnState when balancer.Get(newConfig.ChildPolicy.Name) returns nil. The child policy name comes from the cluster resource's LB policy configuration sent by the management server, which was parsed and stored in the cluster_impl LBConfig.

Common situations: The management server configures an LB policy (e.g., RING_HASH, LEAST_REQUEST) that the gRPC client build doesn't support or hasn't imported; a typo or unsupported policy name in the xDS cluster resource; the weighted_round_robin balancer is not registered (needs import or recent grpc-go version); using a policy that is gated behind an experimental flag or separate import.

Related errors


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