{"record":{"id":"9abc69b90e1b2e60","repo":"grpc/grpc-go","slug":"all-subconns-are-in-transientfailure","errorCode":null,"errorMessage":"all SubConns are in TransientFailure","messagePattern":"all SubConns are in TransientFailure","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"balancer/balancer.go","lineNumber":275,"sourceCode":"\tBytesReceived bool\n\t// ServerLoad is the load received from server. It's usually sent as part of\n\t// trailing metadata.\n\t//\n\t// The only supported type now is *orca_v3.LoadReport.\n\tServerLoad any\n}\n\nvar (\n\t// ErrNoSubConnAvailable indicates no SubConn is available for pick().\n\t// gRPC will block the RPC until a new picker is available via UpdateState().\n\tErrNoSubConnAvailable = errors.New(\"no SubConn is available\")\n\t// ErrTransientFailure indicates all SubConns are in TransientFailure.\n\t// WaitForReady RPCs will block, non-WaitForReady RPCs will fail.\n\t//\n\t// Deprecated: return an appropriate error based on the last resolution or\n\t// connection attempt instead.  The behavior is the same for any non-gRPC\n\t// status error.\n\tErrTransientFailure = errors.New(\"all SubConns are in TransientFailure\")\n)\n\n// PickResult contains information related to a connection chosen for an RPC.\ntype PickResult struct {\n\t// SubConn is the connection to use for this pick, if its state is Ready.\n\t// If the state is not Ready, gRPC will block the RPC until a new Picker is\n\t// provided by the balancer (using ClientConn.UpdateState).  The SubConn\n\t// must be one returned by ClientConn.NewSubConn.\n\tSubConn SubConn\n\n\t// Done is called when the RPC is completed.  If the SubConn is not ready,\n\t// this will be called with a nil parameter.  If the SubConn is not a valid\n\t// type, Done may not be called.  May be nil if the balancer does not wish\n\t// to be notified when the RPC completes.\n\tDone func(DoneInfo)\n\n\t// Metadata provides a way for LB policies to inject arbitrary per-call\n\t// metadata. Any metadata returned here will be merged with existing","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/balancer/balancer.go#L257-L293","documentation":"Thrown by ParseFilterConfigOverride when the override proto.Message is non-nil but cannot be type-asserted to *anypb.Any. The xDS HTTP filter framework is expected to always deliver configurations as *anypb.Any (the canonical xDS wire encoding). Receiving a different proto type indicates a programming error or protocol violation in the framework layer that invoked the filter builder.","triggerScenarios":"The httpfilter.ParseFilterConfigOverride dispatch in the xdsclient unmarshalling code passes a raw proto.Message that is not *anypb.Any — for example, a directly-unmarshalled *rpb.RBACPerRoute or a *pbb.Any from a mismatched proto package. This can happen when a custom httpfilter.Builder implementation or test harness invokes the RBAC builder with the wrong concrete type.","commonSituations":"Unit tests that call ParseFilterConfigOverride with a *rpb.RBACPerRoute directly instead of wrapping it in *anypb.Any. A fork of grpc-go that changed the httpfilter interface to pass untyped protos. Proto import aliasing causing the anypb.Any from google.golang.org/protobuf/types/known/anypb to differ from the one the framework passes.","solutions":["Ensure the value passed to ParseFilterConfigOverride is always *anypb.Any — wrap the proto message with anypb.New(msg) before calling.","If this surfaces from xdsclient internals, verify the grpc-go version is internally consistent (no partial upgrade) so the same anypb.Any type is used throughout.","In test code, use anypb.New(&rpb.RBACPerRoute{...}) instead of passing the bare struct."],"exampleFix":"// before (test or custom caller):\ncfg, err := b.ParseFilterConfigOverride(&rpb.RBACPerRoute{\n    Rbac: &rpb.RBAC{Rules: rules},\n})\n\n// after:\nany, _ := anypb.New(&rpb.RBACPerRoute{\n    Rbac: &rpb.RBAC{Rules: rules},\n})\ncfg, err := b.ParseFilterConfigOverride(any)","handlingStrategy":"type-guard","validationCode":"// Ensure the override is *anypb.Any before calling ParseFilterConfigOverride:\nfunc safeParseOverride(b httpfilter.Builder, override proto.Message) (httpfilter.FilterConfig, error) {\n    if override == nil {\n        return nil, fmt.Errorf(\"override is nil\")\n    }\n    if _, ok := override.(*anypb.Any); !ok {\n        return nil, fmt.Errorf(\"override must be *anypb.Any, got %T; wrap with anypb.New\", override)\n    }\n    return b.ParseFilterConfigOverride(override)\n}","typeGuard":"func isAnypbAny(msg proto.Message) bool {\n    _, ok := msg.(*anypb.Any)\n    return ok\n}","tryCatchPattern":null,"preventionTips":["Always wrap proto configs in anypb.New before passing to httpfilter builders.","In test harnesses, create a helper that always returns *anypb.Any to avoid type mismatches.","Avoid mixing github.com/golang/protobuf ptypes with google.golang.org protobuf anypb."],"tags":["xds","rbac","grpc","type-assertion","proto"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}