grpc/grpc-go · error
no children to pick from
Error message
no children to pick from
What it means
Thrown by ParseFilterConfig when the proto.Message for the Router filter is non-nil but is not *anypb.Any. The xDS framework always encodes filter configs as *anypb.Any; receiving another type signals a caller bug or a proto type mismatch between the framework and the filter builder.
Solutions
- Always pass *anypb.Any to ParseFilterConfig — wrap with anypb.New(&pb.Router{}).
- Ensure all proto imports use google.golang.org/protobuf/types/known/anypb consistently; avoid mixing github.com/golang/protobuf/ptypes/any.
- If the error comes from production xDS flow, verify the grpc-go module version is uniform across the build (go mod why google.golang.org/grpc).
Example fix
// before:
cfg, err := b.ParseFilterConfig(&pb.Router{})
// after:
any, _ := anypb.New(&pb.Router{})
cfg, err := b.ParseFilterConfig(any) Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure cfg is *anypb.Any before dispatching to ParseFilterConfig:
func safeParseConfig(b httpfilter.Builder, cfg proto.Message) (httpfilter.FilterConfig, error) {
any, ok := cfg.(*anypb.Any)
if !ok {
return nil, fmt.Errorf("expected *anypb.Any, got %T", cfg)
}
return b.ParseFilterConfig(any)
} Type guard
func isAnypbAny(msg proto.Message) bool {
_, ok := msg.(*anypb.Any)
return ok
} Prevention
- Standardize on google.golang.org/protobuf/types/known/anypb across the entire build.
- In test code, use a factory helper: func anyOf(m proto.Message) *anypb.Any { a, _ := anypb.New(m); return a }.
- Run go mod tidy and verify there are no competing protobuf versions.
When it happens
Trigger: A custom httpfilter dispatch path or test harness passes a *pb.Router directly to ParseFilterConfig instead of wrapping it in *anypb.Any. A grpc-go fork changed the httpfilter.Builder interface contract. Proto import path divergence causes the anypb.Any type seen by the builder to differ from the one passed.
Common situations: Unit tests of the xdsclient filter unmarshalling that construct filter configs without anypb.New. A mixed-dependency build where google.golang.org/protobuf and github.com/golang/protobuf Any types are interchanged. An internal refactor that bypasses the standard Any wrapping.
Related errors
- all SubConns are in TransientFailure
- produced zero addresses
- produced zero addresses
- bad resolver state
- grpc: credentials.Bundle may not be used with individual…
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/3f5dc3ba51a464f1.
Report an issue: GitHub.
Appendix: source
Thrown at balancer/endpointsharding/endpointsharding.go:293
// the aggregated state, use the pickers present that are currently in that
// state only.
var aggState connectivity.State
var pickers []balancer.Picker
if len(readyPickers) >= 1 {
aggState = connectivity.Ready
pickers = readyPickers
} else if len(connectingPickers) >= 1 {
aggState = connectivity.Connecting
pickers = connectingPickers
} else if len(idlePickers) >= 1 {
aggState = connectivity.Idle
pickers = idlePickers
} else if len(transientFailurePickers) >= 1 {
aggState = connectivity.TransientFailure
pickers = transientFailurePickers
} else {
aggState = connectivity.TransientFailure
pickers = []balancer.Picker{base.NewErrPicker(errors.New("no children to pick from"))}
} // No children (resolver error before valid update).
p := &pickerWithChildStates{
pickers: pickers,
childStates: childStates,
next: uint32(randIntN(len(pickers))),
}
es.cc.UpdateState(balancer.State{
ConnectivityState: aggState,
Picker: p,
})
}
// pickerWithChildStates delegates to the pickers it holds in a round robin
// fashion. It also contains the childStates of all the endpointSharding's
// children.
type pickerWithChildStates struct {
pickers []balancer.Picker
childStates []ChildStateView on GitHub (pinned to 0c51461d27)