grpc/grpc-go · error
unexpected balancer config with type: %T
Error message
unexpected balancer config with type: %T
What it means
The cluster_impl balancer's UpdateClientConnState expects BalancerConfig to be of type *LBConfig (the cluster_impl-specific config struct). This error fires when the config has a different type, indicating a misconfiguration in how the balancer tree was assembled. The config should always be *LBConfig when the CDS/priority balancer properly routes to cluster_impl.
Source
Thrown at internal/xds/balancer/clusterimpl/clusterimpl.go:404
oldHI := b.xdsHIPtr.Swap(newHI)
if oldHI != nil {
oldHI.Decrement()
}
return nil
}
func (b *clusterImplBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
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
}
View on GitHub (pinned to 03255a9237)
Solutions
- This error indicates an internal gRPC configuration error — the balancer tree assembly is broken. Report as a bug with the grpc-go version and xDS configuration
- Verify you are not manually constructing balancer configs for the xDS balancer chain
- Ensure no custom balancer intercepts or replaces the config passed to cluster_impl
- Upgrade grpc-go to a stable release, as this may be a regression
- Enable GRPC_GO_LOG_SEVERITY=info to see what config type was actually received
Defensive patterns
Strategy: type-guard
Validate before calling
// Verify the config type matches before calling UpdateClientConnState
// (applicable if constructing balancer configs programmatically)
func isClusterImplConfig(cfg serviceconfig.LoadBalancingConfig) bool {
_, ok := cfg.(*clusterimpl.LBConfig)
return ok
} Type guard
// Type guard for cluster_impl config
func isClusterImplLBConfig(v interface{}) bool {
_, ok := v.(*clusterimpl.LBConfig)
return ok
} Prevention
- Do not manually construct balancer configs for the xDS balancer chain
- Use standard xDS balancer setup via grpc.NewClient with xds resolver
- Keep grpc-go versions consistent across all imports
- Report unexpected config type errors as bugs
When it happens
Trigger: Triggered at the start of cluster_impl's UpdateClientConnState when the type assertion s.BalancerConfig.(*LBConfig) fails. This means the resolver or parent balancer passed a config of an unexpected type (e.g., a raw map, a different balancer's config struct, or nil).
Common situations: A misconfigured xDS balancer chain where the wrong config type is routed to cluster_impl; a bug in the parent priority or CDS balancer that constructs the wrong config type; manual or programmatic construction of balancer.ClientConnState with incorrect config types; a version mismatch where LBConfig struct layout changed between packages.
Related errors
- xds: failed to create a new channel for server config %v: %v
- extauthz: error parsing override config %v: unknown type %T,
- extproc: error parsing config %v: unknown type %T, want *any
- missing server_listener_resource_name_template in the bootst
- no priority is provided, all priorities are removed
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/89dcb33e87721437.
Report an issue: GitHub.