{"record":{"id":"2cf634e4c8f5bce6","repo":"grpc/grpc-go","slug":"no-peer-found-in-context","errorCode":null,"errorMessage":"no Peer found in Context","messagePattern":"no Peer found in Context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/utils.go","lineNumber":38,"sourceCode":"\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"strings\"\n\n\t\"google.golang.org/grpc/codes\"\n\t\"google.golang.org/grpc/peer\"\n\t\"google.golang.org/grpc/status\"\n)\n\n// 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","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/alts/utils.go#L20-L56","documentation":"Returned by AuthInfoFromContext (credentials/alts/utils.go:35-41) when peer.FromContext(ctx) returns ok==false — the context has no Peer value attached. gRPC normally attaches the peer to a server handler's context after the handshake; calling AuthInfoFromContext on a context that never carried a peer (e.g. a plain context.Background, or a handler invoked before transport setup) triggers it.","triggerScenarios":"AuthInfoFromContext is called on a context that is not (or not yet) a gRPC server handler context — peer.FromContext returns false at utils.go:36-38. Also if the peer was never set because the call path bypassed gRPC transport (e.g. in a unit test, a non-RPC goroutine, or an interceptor that received a fresh context).","commonSituations":"Unit-testing a server handler with context.Background(); calling AuthInfoFromContext inside a streaming handler before the RPC peer is established; sharing auth-check helper code between gRPC and non-gRPC paths; a context overwritten via context.WithValue losing the peer.","solutions":["Call AuthInfoFromContext only inside a gRPC server method/interceptor where gRPC has attached the Peer.","Guard the call: check p, ok := peer.FromContext(ctx) first, and return PermissionDenied/Unauthenticated when !ok.","In tests, inject a peer via peer.NewContext(ctx, &peer.Peer{AuthInfo: fakeALTS}) instead of using a bare context.","Use ClientAuthorizationCheck which already wraps this into a clean codes.PermissionDenied status."],"exampleFix":"// before — helper called on a non-RPC context\nai, err := alts.AuthInfoFromContext(context.Background())\n// err: no Peer found in Context\n\n// after — guard the peer, or inject one in tests\nfunc authorize(ctx context.Context) error {\n    p, ok := peer.FromContext(ctx)\n    if !ok {\n        return status.Error(codes.PermissionDenied, \"no peer\")\n    }\n    return alts.ClientAuthorizationCheck(ctx, allowed)\n}","handlingStrategy":"validation","validationCode":"// Guard Peer before extracting ALTS info\nfunc authorize(ctx context.Context, allowed []string) error {\n    p, ok := peer.FromContext(ctx)\n    if !ok {\n        return status.Error(codes.PermissionDenied, \"no peer in context\")\n    }\n    return alts.ClientAuthorizationCheck(ctx, allowed)\n}","typeGuard":"func hasPeer(ctx context.Context) bool {\n    _, ok := peer.FromContext(ctx)\n    return ok\n}","tryCatchPattern":"if _, err := alts.AuthInfoFromContext(ctx); err != nil {\n    if strings.Contains(err.Error(), \"no Peer found\") {\n        return status.Error(codes.PermissionDenied, \"non-RPC context\")\n    }\n}","preventionTips":["Call AuthInfoFromContext only inside real gRPC handlers/interceptors.","Inject a peer via peer.NewContext in tests.","Prefer alts.ClientAuthorizationCheck for clean status mapping."],"tags":["alts","auth","peer","grpc-go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}