grpc/grpc-go · error
server-side auth info is not of type alts.AuthInfo
Error message
server-side auth info is not of type alts.AuthInfo
What it means
Returned at credentials/alts/alts.go:246-249 (the server-side analogue of error 14) when shs.ServerHandshake succeeds but the AuthInfo it returns fails the `authInfo.(AuthInfo)` type assertion. The server-side ALTS handshake produced an AuthInfo that is not the expected alts.AuthInfo type.
Source
Thrown at credentials/alts/alts.go:248
defer cancel()
opts := handshaker.DefaultServerHandshakerOptions()
opts.RPCVersions = &altspb.RpcProtocolVersions{
MaxRpcVersion: maxRPCVersion,
MinRpcVersion: minRPCVersion,
}
shs, err := handshaker.NewServerHandshaker(ctx, hsConn, rawConn, opts)
if err != nil {
return nil, nil, err
}
secConn, authInfo, err := shs.ServerHandshake(ctx)
if err != nil {
return nil, nil, err
}
// Close the handshaker since we have obtained a connection.
defer shs.Close()
altsAuthInfo, ok := authInfo.(AuthInfo)
if !ok {
return nil, nil, errors.New("server-side auth info is not of type alts.AuthInfo")
}
match, _ := checkRPCVersions(opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
if !match {
return nil, nil, fmt.Errorf("client-side RPC versions is not compatible with this server, local versions: %v, peer versions: %v", opts.RPCVersions, altsAuthInfo.PeerRPCVersions())
}
return secConn, authInfo, nil
}
func (g *altsTC) Info() credentials.ProtocolInfo {
return *g.info
}
func (g *altsTC) Clone() credentials.TransportCredentials {
info := *g.info
var accounts []string
if g.accounts != nil {
accounts = make([]string, len(g.accounts))
copy(accounts, g.accounts)View on GitHub (pinned to 03255a9237)
Solutions
- Upgrade the grpc + alts + handshaker module set together and run go mod tidy.
- Make sure no middleware rewraps the net.Conn/AuthInfo returned by ServerHandshake before gRPC reads it.
- Confirm you are on GCP using the real handshaker service (vmOnGCP true).
- Add an integration test on GCP that asserts AuthInfoFromContext(ctx) returns non-nil alts.AuthInfo.
Example fix
// before — server registers ALTS but a Conn wrapper swaps AuthInfo creds := alts.NewServerCreds(opts) srv := grpc.NewServer(grpc.Creds(creds)) // a transport interceptor replaced AuthInfo -> 'server-side auth info is not of type alts.AuthInfo' // after — pass rawConn/AuthInfo through unmodified creds := alts.NewServerCreds(opts) srv := grpc.NewServer(grpc.Creds(creds))
Defensive patterns
Strategy: type-guard
Validate before calling
// Server-side: confirm ALTS creds are registered before relying on ALTS AuthInfo srv := grpc.NewServer(grpc.Creds(alts.NewServerCreds(alts.DefaultServerOptions())))
Type guard
func isALTSAuthInfo(ai credentials.AuthInfo) bool {
_, ok := ai.(alts.AuthInfo)
return ok
} Try / catch
ai, err := alts.AuthInfoFromContext(ctx)
if err != nil {
// likely non-ALTS transport or module skew; check creds + module versions
} Prevention
- Keep grpc + alts + handshaker module versions aligned.
- Don't let middleware swap the server transport's AuthInfo.
- Run ALTS integration tests on GCP.
When it happens
Trigger: Server-side altsTC.ServerHandshake finishes the handshaker exchange, but the returned AuthInfo does not implement alts.AuthInfo. Same root causes as the client side: handshaker/proto module skew or a tampered rawConn/AuthInfo path.
Common situations: Version mismatch between the server's grpc/alts modules and the ALTS handshaker; outdated vendored alts; a proxy/in-process wrapper that replaces AuthInfo on the server transport.
Related errors
- ALTS: untrusted platform. ALTS is only supported on GCP
- client-side auth info is not of type alts.AuthInfo
- grpc: no transport security set (use grpc.WithTransportCrede
- grpc: credentials.Bundle may not be used with individual Tra
- grpc: credentials.Bundle must return non-nil transport crede
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/ecf674f4fa11fbfc.
Report an issue: GitHub.