grpc/grpc-go · error
produced zero addresses
Error message
produced zero addresses
What it means
Thrown when the *anypb.Any for the Router filter fails to unmarshal into *pb.Router. The payload bytes do not form a valid Router proto — either the type_url is wrong, the bytes are corrupt, or there is a go-control-plane schema version mismatch between the control plane and grpc-go.
Source
Thrown at balancer/pickfirst/pickfirst.go:219
return
}
b.updateBalancerState(balancer.State{
ConnectivityState: connectivity.TransientFailure,
Picker: &picker{err: fmt.Errorf("name resolver error: %v", err)},
})
}
func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error {
b.mu.Lock()
defer b.mu.Unlock()
b.cancelConnectionTimer()
if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 {
// Cleanup state pertaining to the previous resolver state.
// Treat an empty address list like an error by calling b.ResolverError.
b.closeSubConnsLocked()
b.addressList.updateAddrs(nil)
b.resolverErrorLocked(errors.New("produced zero addresses"))
return balancer.ErrBadResolverState
}
b.healthCheckingEnabled = state.ResolverState.Attributes.Value(enableHealthListenerKeyType{}) != nil
cfg, ok := state.BalancerConfig.(pfConfig)
if state.BalancerConfig != nil && !ok {
return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v: %w", state.BalancerConfig, state.BalancerConfig, balancer.ErrBadResolverState)
}
if b.logger.V(2) {
b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState))
}
var newAddrs []resolver.Address
if endpoints := state.ResolverState.Endpoints; len(endpoints) != 0 {
// Perform the optional shuffling described in gRFC A62. The shuffling
// will change the order of endpoints but not touch the order of the
// addresses within each endpoint. - A61
if cfg.ShuffleAddressList {View on GitHub (pinned to 0c51461d27)
Solutions
- Confirm the Any type_url is type.googleapis.com/envoy.extensions.filters.http.router.v3.Router and the payload is a valid (possibly empty) Router message.
- Align go-control-plane versions between the control plane and the grpc-go data plane.
- Decode the Any payload with protoc --decode_raw or grpcurl to inspect the actual bytes, and fix the control-plane serialization.
Example fix
// before: wrong type_url in the Any
any := &anypb.Any{
TypeUrl: "type.googleapis.com/envoy.extensions.filters.http.router.v3.RouterConfig",
Value: rawBytes,
}
// after:
any, _ := anypb.New(&pb.Router{}) // correct type_url auto-set Defensive patterns
Strategy: validation
Validate before calling
// Validate the Router filter Any before parsing:
func validateRouterAny(any *anypb.Any) error {
expected := "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
if any.TypeUrl != expected {
return fmt.Errorf("router type_url mismatch: want %s, got %s", expected, any.TypeUrl)
}
msg := new(pb.Router)
return any.UnmarshalTo(msg)
} Prevention
- Use anypb.New(&pb.Router{}) which auto-sets the correct type_url.
- Align go-control-plane versions between control plane and grpc-go.
- Run integration tests that verify the full LDS -> filter build pipeline with the actual control plane output.
When it happens
Trigger: The Any's type_url does not match type.googleapis.com/envoy.extensions.filters.http.router.v3.Router, or the serialized bytes correspond to a different proto version of Router. A DiscoveryResponse with a corrupt or truncated filter config payload. A control plane using a newer Router proto with unknown fields that fail strict unmarshalling.
Common situations: Control plane upgraded go-control-plane to a version with breaking proto changes without upgrading grpc-go. A hand-crafted LDS resource with a copy-paste type_url from a different filter. Network-level corruption of the xDS DiscoveryResponse.
Related errors
- bad resolver state
- produced zero addresses
- no children to pick from
- no SubConn is available
- all SubConns are in TransientFailure
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/175bd982d336d7fd.
Report an issue: GitHub.