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

Returned at credentials/alts/alts.go:206-209 when, after a successful ClientHandshake against the ALTS handshaker, the AuthInfo it produced does not satisfy the alts.AuthInfo interface (type assertion `authInfo.(AuthInfo)` failed). This means the handshaker returned an unexpected/older AuthInfo shape.

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 03255a9237)

Solutions

  1. Align versions: update google.golang.org/grpc, google.golang.org/grpc/credentials/alts, and the ALTS handshaker/proto modules together.
  2. Run go mod tidy and verify there are no duplicate/old alts packages in the module graph.
  3. If you wrap the connection, ensure you forward the original AuthInfo rather than substituting one.
  4. Reproduce on GCP with the real handshaker; if it works there, the issue is your local/fake handshaker.

Example fix

// before — stale ALTS handshaker module returns incompatible AuthInfo
// (go.mod pins old google.golang.org/grpc/alts/internal/handshaker)

// after — bump all gRPC+ALTS modules in lockstep
//   go get google.golang.org/grpc@latest
//   go get google.golang.org/grpc/credentials/alts@latest
//   go mod tidy
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify the handshaker produces ALTS AuthInfo before relying on it
// (defensive — the assertion already happens inside ClientHandshake)
// Prefer: align module versions so the assertion never fails.

Type guard

func isALTSAuthInfo(ai credentials.AuthInfo) bool {
    _, ok := ai.(alts.AuthInfo)
    return ok
}

Try / catch

// Wrap ALTS dial with a fallback / clearer error
ai, err := alts.AuthInfoFromPeer(peer)
if err != nil {
    // version skew likely; bump grpc + alts modules and go mod tidy
}

Prevention

When it happens

Trigger: altsTC.ClientHandshake completes chs.ClientHandshake(ctx) without error but the returned credentials.AuthInfo is not assignable to the alts.AuthInfo interface. Causes: handshaker library version skew, a custom/rawConn passed through a wrapper that swapped AuthInfo, or a malformed handshaker response.

Common situations: Mismatched versions of google.golang.org/grpc and the ALTS handshaker/proto packages; vendored outdated copy of the alts subpackage; testing with a fake handshaker returning a non-ALTS AuthInfo; gRPC upgrade without updating ALTS deps.

Related errors


AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07). Data as JSON: /api/errors/4fdf98f88b6e91c0. Report an issue: GitHub.