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

  1. Upgrade grpc-go to a version whose matchersFromPrincipals enumerates the principal type the control plane sends.
  2. 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).
  3. 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

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


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)