{"record":{"id":"4c1102b3d11fa244","repo":"grpc/grpc-go","slug":"authinfo-is-nil","errorCode":null,"errorMessage":"AuthInfo is nil","messagePattern":"AuthInfo is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/credentials.go","lineNumber":295,"sourceCode":"// in ctx.\n//\n// This API is experimental.\nfunc ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {\n\tchi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)\n\treturn chi\n}\n\n// CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.\n// It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method\n// or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.\n//\n// This API is experimental.\nfunc CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {\n\ttype internalInfo interface {\n\t\tGetCommonAuthInfo() CommonAuthInfo\n\t}\n\tif ai == nil {\n\t\treturn errors.New(\"AuthInfo is nil\")\n\t}\n\tif ci, ok := ai.(internalInfo); ok {\n\t\t// CommonAuthInfo.SecurityLevel has an invalid value.\n\t\tif ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {\n\t\t\treturn nil\n\t\t}\n\t\tif ci.GetCommonAuthInfo().SecurityLevel < level {\n\t\t\treturn fmt.Errorf(\"requires SecurityLevel %v; connection has %v\", level, ci.GetCommonAuthInfo().SecurityLevel)\n\t\t}\n\t}\n\t// The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.\n\treturn nil\n}\n\n// ChannelzSecurityInfo defines the interface that security protocols should implement\n// in order to provide security info to channelz.\n//\n// This API is experimental.","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/credentials.go#L277-L313","documentation":"Returned by credentials.CheckSecurityLevel (credentials/credentials.go:290-296) when the AuthInfo argument is nil. CheckSecurityLevel is an experimental helper used to assert a connection meets a minimum SecurityLevel; the nil guard at :294-296 fires before the level comparison.","triggerScenarios":"CheckSecurityLevel(ai, level) is called with ai==nil. This occurs when callers pass a nil AuthInfo — e.g. before the handshake completed, a path that never set AuthInfo, or a test/mocked value that left it nil.","commonSituations":"Server interceptor calling CheckSecurityLevel on a Peer.AuthInfo that was nil (insecure/failed handshake); tests passing nil; a custom credentials path that didn't populate AuthInfo; calling the check before transport establishment.","solutions":["Null-check AuthInfo before calling CheckSecurityLevel: if p.AuthInfo == nil { return Unauthenticated }.","Ensure the connection actually completed a handshake so AuthInfo is populated (use real or fake non-nil creds in tests).","For insecure connections, pass an AuthInfo whose CommonAuthInfo.SecurityLevel is intentionally set (or accept the nil check as a denial).","Treat a nil AuthInfo as a security failure (deny) rather than letting the helper error propagate raw."],"exampleFix":"// before — passes possibly-nil AuthInfo straight to the helper\np, _ := peer.FromContext(ctx)\nif err := credentials.CheckSecurityLevel(p.AuthInfo, credentials.PrivacyAndIntegrity); err != nil {\n    return err // 'AuthInfo is nil' leaks to caller\n}\n\n// after — guard nil first and deny cleanly\np, ok := peer.FromContext(ctx)\nif !ok || p.AuthInfo == nil {\n    return status.Error(codes.Unauthenticated, \"missing auth info\")\n}\nif err := credentials.CheckSecurityLevel(p.AuthInfo, credentials.PrivacyAndIntegrity); err != nil {\n    return status.Error(codes.PermissionDenied, err.Error())\n}","handlingStrategy":"validation","validationCode":"// Null-check AuthInfo before calling CheckSecurityLevel\nfunc requireLevel(ctx context.Context, lvl credentials.SecurityLevel) error {\n    p, ok := peer.FromContext(ctx)\n    if !ok || p.AuthInfo == nil {\n        return status.Error(codes.Unauthenticated, \"missing auth info\")\n    }\n    return credentials.CheckSecurityLevel(p.AuthInfo, lvl)\n}","typeGuard":"func hasAuthInfo(p *peer.Peer) bool {\n    return p != nil && p.AuthInfo != nil\n}","tryCatchPattern":"if err := credentials.CheckSecurityLevel(ai, lvl); err != nil {\n    if strings.Contains(err.Error(), \"AuthInfo is nil\") {\n        return status.Error(codes.Unauthenticated, \"no auth info\")\n    }\n    return status.Error(codes.PermissionDenied, err.Error())\n}","preventionTips":["Always null-check Peer.AuthInfo before CheckSecurityLevel.","Use non-nil AuthInfo in tests (real or fake creds).","Treat nil AuthInfo as a denial, not a propagated error string."],"tags":["credentials","security","auth-info","grpc-go"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}