grpc/grpc-go · info
credentials: rawConn is dispatched out of gRPC
Error message
credentials: rawConn is dispatched out of gRPC
What it means
ErrConnDispatched is a sentinel error (not a real failure) that a custom TransportCredentials implementation returns from ClientHandshake or ServerHandshake to signal that it has taken ownership of the underlying net.Conn and routed it outside of gRPC (e.g., to a proxy or in-process handler). gRPC checks for this exact error and, when seen, does NOT close the connection and does not treat it as a handshake failure.
Solutions
- If you are the credential author, ensure you return credentials.ErrConnDispatched (not a wrapped variant) so gRPC's exact-equality check (err == credentials.ErrConnDispatched) matches.
- If you see this in application-level error handling, treat it as non-fatal: do not retry or close the connection; gRPC already handles it.
- Use errors.Is or direct equality only if you are building transport-level code that inspects handshake results.
Example fix
// before
customConn, err := myProxy.Route(rawConn)
if err != nil { return nil, nil, fmt.Errorf("dispatch failed: %w", err) }
return nil, nil, errors.New("dispatched") // gRPC closes the conn
// after
customConn, err := myProxy.Route(rawConn)
if err != nil { return nil, nil, err }
return nil, nil, credentials.ErrConnDispatched // gRPC leaves conn open Defensive patterns
Strategy: validation
Validate before calling
// If inspecting handshake results in transport-level code:
if err == credentials.ErrConnDispatched {
// expected: conn was routed elsewhere, do not close
return nil
} Try / catch
// This is a sentinel, not a failure. Handle with direct equality:
if err == credentials.ErrConnDispatched || err == io.EOF {
// normal control flow; do not treat as error
} Prevention
- Return the exact sentinel (credentials.ErrConnDispatched) from custom handshakers, not a wrapped error.
- Treat this error as info-level control flow in logs.
- Never close the connection when this sentinel is returned.
When it happens
Trigger: A custom TransportCredentials.ServerHandshake or ClientHandshake implementation returns credentials.ErrConnDispatched after handing the raw net.Conn to a non-gRPC consumer (e.g., an HTTP/1 proxy, a TLS-termination sidecar, or an in-process listener). The error then propagates up through transport.NewServerTransport or grpc.Dial's connection setup.
Common situations: Developers writing custom proxy or connection-pooling credentials that intercept certain connections. Also seen with the internal proxyattributes package or custom listener wrappers that conditionally route traffic. The error is expected control flow, not a bug — but it surfaces in logs if not handled correctly.
Related errors
- AuthInfo is nil
- ClientHandshake() is not supported for server credentials
- empty token_exchange_service_uri in options
- failed to build call credentials from bootstrap for
- failed to build credentials bundle from bootstrap for
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/12055abafda736ab.
Report an issue: GitHub.
Appendix: source
Thrown at credentials/credentials.go:148
}
// AuthorityValidator validates the authority used to override the `:authority`
// header. This is an optional interface that implementations of AuthInfo can
// implement if they support per-RPC authority overrides. It is invoked when the
// application attempts to override the HTTP/2 `:authority` header using the
// CallAuthority call option.
type AuthorityValidator interface {
// ValidateAuthority checks the authority value used to override the
// `:authority` header. The authority parameter is the override value
// provided by the application via the CallAuthority option. This value
// typically corresponds to the server hostname or endpoint the RPC is
// targeting. It returns non-nil error if the validation fails.
ValidateAuthority(authority string) error
}
// ErrConnDispatched indicates that rawConn has been dispatched out of gRPC
// and the caller should not close rawConn.
var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gRPC")
// TransportCredentials defines the common interface for all the live gRPC wire
// protocols and supported transport security protocols (e.g., TLS, SSL).
type TransportCredentials interface {
// ClientHandshake does the authentication handshake specified by the
// corresponding authentication protocol on rawConn for clients. It returns
// the authenticated connection and the corresponding auth information
// about the connection. The auth information should embed CommonAuthInfo
// to return additional information about the credentials. Implementations
// must use the provided context to implement timely cancellation. gRPC
// will try to reconnect if the error returned is a temporary error
// (io.EOF, context.DeadlineExceeded or err.Temporary() == true). If the
// returned error is a wrapper error, implementations should make sure that
// the error implements Temporary() to have the correct retry behaviors.
// Additionally, ClientHandshakeInfo data will be available via the context
// passed to this call.
//
// The second argument to this method is the `:authority` header value usedView on GitHub (pinned to 0c51461d27)