grpc/grpc-go · error
client-side auth info is not of type alts.AuthInfo
Error message
client-side auth info is not of type alts.AuthInfo
What it means
Thrown by matchersFromPrincipals in its default switch case when a Principal proto's Identifier oneof is set to a variant that gRPC RBAC does not handle. The supported principal types are: AndIds, OrIds, Any, Authenticated, DirectRemoteIp, Header, UrlPath, Metadata, NotId, SourceIp, and RemoteIp. Any other variant triggers this error, failing the engine build.
Solutions
- Upgrade grpc-go to a version whose matchersFromPrincipals enumerates the principal type the control plane sends.
- Remove the unsupported principal identifier from the policy and use only supported types (and_ids, or_ids, any, authenticated, direct_remote_ip, header, url_path, metadata, not_id, source_ip, remote_ip).
- Replace an unsupported identity check with an equivalent supported one — e.g., use authenticated with a principal_name string matcher instead of a custom claim-based principal.
Example fix
// before: control plane uses an unsupported principal type
principals:
- someNewIdentifier: {claim: "sub", value: "admin"}
// after: use authenticated with principal_name matcher
principals:
- authenticated:
principal_name:
exact: "spiffe://example.org/admin" Defensive patterns
Strategy: validation
Validate before calling
// Validate all principal types are supported before building the engine:
func validatePrincipals(principals []*v3rbacpb.Principal) error {
for _, p := range principals {
switch p.GetIdentifier().(type) {
case *v3rbacpb.Principal_AndIds:
if err := validatePrincipals(p.GetAndIds().GetIds()); err != nil { return err }
case *v3rbacpb.Principal_OrIds:
if err := validatePrincipals(p.GetOrIds().GetIds()); err != nil { return err }
case *v3rbacpb.Principal_Any, *v3rbacpb.Principal_Authenticated_,
*v3rbacpb.Principal_DirectRemoteIp, *v3rbacpb.Principal_Header,
*v3rbacpb.Principal_UrlPath, *v3rbacpb.Principal_Metadata,
*v3rbacpb.Principal_NotId, *v3rbacpb.Principal_SourceIp,
*v3rbacpb.Principal_RemoteIp:
// supported
default:
return fmt.Errorf("unsupported principal type %T", p.GetIdentifier())
}
}
return nil
} Prevention
- Keep grpc-go and go-control-plane versions aligned.
- Audit RBAC policies for unsupported principal types before deploying to the data plane.
- Use authenticated principal_name matchers instead of custom claim-based principals for identity checks.
When it happens
Trigger: A control plane sends an RBAC policy whose principals include an identifier type not implemented by this version of grpc-go. For example, a newer Envoy proto adds a Principal identifier (like a JWT-claim-based principal or a TLS session ID principal) that the switch does not handle. The error propagates from newPolicyMatcher -> newEngine -> NewChainEngine, causing the xDS resource to be NACKed.
Common situations: Version skew: control plane runs a newer go-control-plane with additional Principal variants. A new Envoy RBAC principal extension deployed before grpc-go support. Custom proto extensions with non-standard principal identifiers.
Related errors
- ALTS: untrusted platform. ALTS is only supported on GCP
- grpc: credentials.Bundle may not be used with individual…
- unknown header matcher type
- all SubConns are in TransientFailure
- bad resolver state
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/4fdf98f88b6e91c0.
Report an issue: GitHub.
Appendix: source
Thrown at credentials/alts/alts.go:208
opts.TargetServiceAccounts = g.accounts
opts.RPCVersions = &altspb.RpcProtocolVersions{
MaxRpcVersion: maxRPCVersion,
MinRpcVersion: minRPCVersion,
}
opts.BoundAccessToken = g.boundAccessToken
chs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, opts)
if err != nil {
return nil, nil, err
}
// Close the handshaker since we have obtained a connection.
defer chs.Close()
secConn, authInfo, err := chs.ClientHandshake(ctx)
if err != nil {
return nil, nil, err
}
altsAuthInfo, ok := authInfo.(AuthInfo)
if !ok {
return nil, nil, errors.New("client-side auth info is not of type alts.AuthInfo")
}
match, _ := checkRPCVersions(opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
if !match {
return nil, nil, fmt.Errorf("server-side RPC versions are not compatible with this client, local versions: %v, peer versions: %v", opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
}
return secConn, authInfo, nil
}
// ServerHandshake implements the server side ALTS handshaker.
func (g *altsTC) ServerHandshake(rawConn net.Conn) (_ net.Conn, _ credentials.AuthInfo, err error) {
if !vmOnGCP {
return nil, nil, ErrUntrustedPlatform
}
// Connecting to ALTS handshaker service.
hsConn, err := service.Dial(g.hsAddress)
if err != nil {
return nil, nil, err
}View on GitHub (pinned to 0c51461d27)