{"record":{"id":"4fdf98f88b6e91c0","repo":"grpc/grpc-go","slug":"client-side-auth-info-is-not-of-type-alts-authinfo","errorCode":null,"errorMessage":"client-side auth info is not of type alts.AuthInfo","messagePattern":"client-side auth info is not of type alts\\.AuthInfo","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/alts.go","lineNumber":208,"sourceCode":"\topts.TargetServiceAccounts = g.accounts\n\topts.RPCVersions = &altspb.RpcProtocolVersions{\n\t\tMaxRpcVersion: maxRPCVersion,\n\t\tMinRpcVersion: minRPCVersion,\n\t}\n\topts.BoundAccessToken = g.boundAccessToken\n\tchs, err := handshaker.NewClientHandshaker(ctx, hsConn, rawConn, opts)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\t// Close the handshaker since we have obtained a connection.\n\tdefer chs.Close()\n\tsecConn, authInfo, err := chs.ClientHandshake(ctx)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\taltsAuthInfo, ok := authInfo.(AuthInfo)\n\tif !ok {\n\t\treturn nil, nil, errors.New(\"client-side auth info is not of type alts.AuthInfo\")\n\t}\n\tmatch, _ := checkRPCVersions(opts.RPCVersions, altsAuthInfo.PeerRPCVersions())\n\tif !match {\n\t\treturn nil, nil, fmt.Errorf(\"server-side RPC versions are not compatible with this client, local versions: %v, peer versions: %v\", opts.RPCVersions, altsAuthInfo.PeerRPCVersions())\n\t}\n\treturn secConn, authInfo, nil\n}\n\n// ServerHandshake implements the server side ALTS handshaker.\nfunc (g *altsTC) ServerHandshake(rawConn net.Conn) (_ net.Conn, _ credentials.AuthInfo, err error) {\n\tif !vmOnGCP {\n\t\treturn nil, nil, ErrUntrustedPlatform\n\t}\n\t// Connecting to ALTS handshaker service.\n\thsConn, err := service.Dial(g.hsAddress)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/alts/alts.go#L190-L226","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Align versions: update google.golang.org/grpc, google.golang.org/grpc/credentials/alts, and the ALTS handshaker/proto modules together.","Run go mod tidy and verify there are no duplicate/old alts packages in the module graph.","If you wrap the connection, ensure you forward the original AuthInfo rather than substituting one.","Reproduce on GCP with the real handshaker; if it works there, the issue is your local/fake handshaker."],"exampleFix":"// before — stale ALTS handshaker module returns incompatible AuthInfo\n// (go.mod pins old google.golang.org/grpc/alts/internal/handshaker)\n\n// after — bump all gRPC+ALTS modules in lockstep\n//   go get google.golang.org/grpc@latest\n//   go get google.golang.org/grpc/credentials/alts@latest\n//   go mod tidy","handlingStrategy":"type-guard","validationCode":"// Verify the handshaker produces ALTS AuthInfo before relying on it\n// (defensive — the assertion already happens inside ClientHandshake)\n// Prefer: align module versions so the assertion never fails.","typeGuard":"func isALTSAuthInfo(ai credentials.AuthInfo) bool {\n    _, ok := ai.(alts.AuthInfo)\n    return ok\n}","tryCatchPattern":"// Wrap ALTS dial with a fallback / clearer error\nai, err := alts.AuthInfoFromPeer(peer)\nif err != nil {\n    // version skew likely; bump grpc + alts modules and go mod tidy\n}","preventionTips":["Bump google.golang.org/grpc and credentials/alts together.","Run go mod tidy to remove duplicate alts packages.","Do not substitute AuthInfo in custom conn wrappers."],"tags":["alts","security","version-skew","grpc-go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}