{"record":{"id":"63d7a117e2b9212f","repo":"grpc/grpc-go","slug":"no-alts-authinfo-found-in-peer","errorCode":null,"errorMessage":"no alts.AuthInfo found in Peer","messagePattern":"no alts\\.AuthInfo found in Peer","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/utils.go","lineNumber":49,"sourceCode":"// AuthInfoFromContext extracts the alts.AuthInfo object from the given context,\n// if it exists. This API should be used by gRPC server RPC handlers to get\n// information about the communicating peer. For client-side, use grpc.Peer()\n// CallOption.\nfunc AuthInfoFromContext(ctx context.Context) (AuthInfo, error) {\n\tp, ok := peer.FromContext(ctx)\n\tif !ok {\n\t\treturn nil, errors.New(\"no Peer found in Context\")\n\t}\n\treturn AuthInfoFromPeer(p)\n}\n\n// AuthInfoFromPeer extracts the alts.AuthInfo object from the given peer, if it\n// exists. This API should be used by gRPC clients after obtaining a peer object\n// using the grpc.Peer() CallOption.\nfunc AuthInfoFromPeer(p *peer.Peer) (AuthInfo, error) {\n\taltsAuthInfo, ok := p.AuthInfo.(AuthInfo)\n\tif !ok {\n\t\treturn nil, errors.New(\"no alts.AuthInfo found in Peer\")\n\t}\n\treturn altsAuthInfo, nil\n}\n\n// ClientAuthorizationCheck checks whether the client is authorized to access\n// the requested resources based on the given expected client service accounts.\n// This API should be used by gRPC server RPC handlers. This API should not be\n// used by clients.\nfunc ClientAuthorizationCheck(ctx context.Context, expectedServiceAccounts []string) error {\n\tauthInfo, err := AuthInfoFromContext(ctx)\n\tif err != nil {\n\t\treturn status.Errorf(codes.PermissionDenied, \"The context is not an ALTS-compatible context: %v\", err)\n\t}\n\tpeer := authInfo.PeerServiceAccount()\n\tfor _, sa := range expectedServiceAccounts {\n\t\tif strings.EqualFold(peer, sa) {\n\t\t\treturn nil\n\t\t}","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/alts/utils.go#L31-L67","documentation":"Returned by alts.AuthInfoFromPeer when the peer's AuthInfo field is not of the alts.AuthInfo type. The function performs a Go type assertion (p.AuthInfo.(AuthInfo)) which fails if the connection was established with non-ALTS credentials such as TLS, insecure, or xDS credentials. This means the active transport security does not use the ALTS protocol.","triggerScenarios":"Calling alts.AuthInfoFromPeer on a peer obtained from a connection that uses credentials.NewTLS, insecure.NewCredentials, or any non-ALTS TransportCredentials. Also triggered when ClientAuthorizationCheck is invoked on a context whose connection was not negotiated with ALTS.","commonSituations":"A server configured with mixed or fallback credentials (e.g., xDS with TLS fallback) receives a connection that did not negotiate ALTS. Developers assume all connections use ALTS but the channel was created with TLS or insecure credentials. Common during migrations from ALTS to TLS or when testing locally without the ALTS handshake server.","solutions":["Verify the channel/server is actually using alts.NewClientCredentials or alts.NewServerCredentials as its TransportCredentials.","Before calling ALTS-specific helpers, check the AuthType of the peer's AuthInfo and branch to the appropriate credential logic.","If the deployment does not require ALTS, switch to the TLS AuthInfo equivalents (credentials.TLSInfo)."],"exampleFix":"// before\nai, err := alts.AuthInfoFromPeer(peer) // fails on TLS connections\n// after\nswitch ai := peer.AuthInfo.(type) {\ncase alts.AuthInfo:\n    // ALTS-specific authorization\ncase credentials.TLSInfo:\n    // TLS-specific authorization\ndefault:\n    return status.Error(codes.Unauthenticated, \"unsupported credentials\")\n}","handlingStrategy":"type-guard","validationCode":"// Check AuthInfo type before calling ALTS-specific helpers:\nfunc isALTSAuthInfo(p *peer.Peer) bool {\n    _, ok := p.AuthInfo.(alts.AuthInfo)\n    return ok\n}","typeGuard":"func isALTSAuthInfo(p *peer.Peer) bool {\n    _, ok := p.AuthInfo.(alts.AuthInfo)\n    return ok\n}","tryCatchPattern":"ai, err := alts.AuthInfoFromPeer(p)\nif err != nil {\n    // connection is not ALTS; handle TLS or insecure accordingly\n    return status.Error(codes.Unauthenticated, \"ALTS credentials required\")\n}","preventionTips":["Check p.AuthInfo.(type) with a switch before using credential-specific helpers.","Confirm the channel was created with alts credentials before calling ALTS helpers.","Document credential assumptions in handler functions."],"tags":["go","grpc","alts","credentials","type-assertion"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}