grpc/grpc-go · error

all SubConns are in TransientFailure

Error message

all SubConns are in TransientFailure

What it means

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.

Solutions

  1. Ensure the value passed to ParseFilterConfigOverride is always *anypb.Any — wrap the proto message with anypb.New(msg) before calling.
  2. 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.
  3. In test code, use anypb.New(&rpb.RBACPerRoute{...}) instead of passing the bare struct.

Example fix

// before (test or custom caller):
cfg, err := b.ParseFilterConfigOverride(&rpb.RBACPerRoute{
    Rbac: &rpb.RBAC{Rules: rules},
})

// after:
any, _ := anypb.New(&rpb.RBACPerRoute{
    Rbac: &rpb.RBAC{Rules: rules},
})
cfg, err := b.ParseFilterConfigOverride(any)
Defensive patterns

Strategy: type-guard

Validate before calling

// Ensure the override is *anypb.Any before calling ParseFilterConfigOverride:
func safeParseOverride(b httpfilter.Builder, override proto.Message) (httpfilter.FilterConfig, error) {
    if override == nil {
        return nil, fmt.Errorf("override is nil")
    }
    if _, ok := override.(*anypb.Any); !ok {
        return nil, fmt.Errorf("override must be *anypb.Any, got %T; wrap with anypb.New", override)
    }
    return b.ParseFilterConfigOverride(override)
}

Type guard

func isAnypbAny(msg proto.Message) bool {
    _, ok := msg.(*anypb.Any)
    return ok
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/9abc69b90e1b2e60. Report an issue: GitHub.

Appendix: source

Thrown at balancer/balancer.go:275

	BytesReceived bool
	// ServerLoad is the load received from server. It's usually sent as part of
	// trailing metadata.
	//
	// The only supported type now is *orca_v3.LoadReport.
	ServerLoad any
}

var (
	// ErrNoSubConnAvailable indicates no SubConn is available for pick().
	// gRPC will block the RPC until a new picker is available via UpdateState().
	ErrNoSubConnAvailable = errors.New("no SubConn is available")
	// ErrTransientFailure indicates all SubConns are in TransientFailure.
	// WaitForReady RPCs will block, non-WaitForReady RPCs will fail.
	//
	// Deprecated: return an appropriate error based on the last resolution or
	// connection attempt instead.  The behavior is the same for any non-gRPC
	// status error.
	ErrTransientFailure = errors.New("all SubConns are in TransientFailure")
)

// PickResult contains information related to a connection chosen for an RPC.
type PickResult struct {
	// SubConn is the connection to use for this pick, if its state is Ready.
	// If the state is not Ready, gRPC will block the RPC until a new Picker is
	// provided by the balancer (using ClientConn.UpdateState).  The SubConn
	// must be one returned by ClientConn.NewSubConn.
	SubConn SubConn

	// Done is called when the RPC is completed.  If the SubConn is not ready,
	// this will be called with a nil parameter.  If the SubConn is not a valid
	// type, Done may not be called.  May be nil if the balancer does not wish
	// to be notified when the RPC completes.
	Done func(DoneInfo)

	// Metadata provides a way for LB policies to inject arbitrary per-call
	// metadata. Any metadata returned here will be merged with existing

View on GitHub (pinned to 0c51461d27)