{"record":{"id":"a9dfbcb8b6989341","repo":"grpc/grpc-go","slug":"credentials-ctx-cannot-be-nil","errorCode":null,"errorMessage":"credentials: ctx cannot be nil","messagePattern":"credentials: ctx cannot be nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/google/gcp_service_account_identity_credentials.go","lineNumber":99,"sourceCode":"// audience.\n//\n// This credential fetches the ID token from the GCE metadata server and is\n// only valid for use in environments running on GCP. The ctx and audience\n// parameters cannot be empty.\n//\n// The credentials object starts asynchronous background token fetches to\n// refresh expired tokens. The provided context propagates cancellation to\n// these background tasks. Users should not pass an RPC-scoped context here,\n// but rather a context that is valid for the entire lifetime of the\n// credentials and should cancel the context when they are done.\n//\n// # Experimental\n//\n// Notice: This API is EXPERIMENTAL and may be changed or removed in a\n// later release.\nfunc NewServiceAccountIdentityCredentials(ctx context.Context, audience string) (credentials.PerRPCCredentials, error) {\n\tif ctx == nil {\n\t\treturn nil, fmt.Errorf(\"credentials: ctx cannot be nil\")\n\t}\n\n\tif audience == \"\" {\n\t\treturn nil, fmt.Errorf(\"credentials: audience cannot be empty\")\n\t}\n\n\tcreds, err := internal.NewIDTokenCredentials(&idtoken.Options{Audience: audience})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"credentials: failed to create ID token credentials: %v\", err)\n\t}\n\n\treturn &gcpServiceAccountIdentityCallCreds{\n\t\tctx:      ctx,\n\t\taudience: audience,\n\t\tcreds:    creds,\n\t\tbackoff:  internal.BackoffStrategy,\n\t}, nil\n}","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/google/gcp_service_account_identity_credentials.go#L81-L117","documentation":"NewServiceAccountIdentityCredentials returns this when its ctx parameter is nil (gcp_service_account_identity_credentials.go:98-100). The context is stored on the credential and used for the lifetime of background token fetches, so a nil context cannot be tolerated. This is a hard programmer-error guard, not a runtime/network condition.","triggerScenarios":"Calling google.NewServiceAccountIdentityCredentials(nil, audience) — typically when a caller propagated an unset context variable, a constructor received nil from a parent struct, or a refactor forgot to thread context.Background().","commonSituations":"Initializing credentials in a package-level var before main wires up contexts, passing nil from a struct field defaulted to nil, or test scaffolding that did not pass a context.","solutions":["Pass a non-nil context — for long-lived creds use context.Background() (or a context you cancel at shutdown), never an RPC-scoped context.","Add a nil-check in your own wiring code to fail at startup with a clearer message.","If the context lifetime is unclear, pass context.Background() and manage shutdown via cancel."],"exampleFix":"// before\ncreds, err := google.NewServiceAccountIdentityCredentials(nil, aud)\n\n// after\nctx, cancel := context.WithCancel(context.Background())\ndefer cancel()\ncreds, err := google.NewServiceAccountIdentityCredentials(ctx, aud)","handlingStrategy":"validation","validationCode":"// Validate context before constructing the credential.\nif ctx == nil {\n    return nil, errors.New(\"caller bug: ctx is nil; pass context.Background()\")\n}\ncreds, err := google.NewServiceAccountIdentityCredentials(ctx, audience)","typeGuard":null,"tryCatchPattern":"creds, err := google.NewServiceAccountIdentityCredentials(ctx, aud)\nif err != nil {\n    if strings.Contains(err.Error(), \"ctx cannot be nil\") {\n        // programmer error: fix the call site.\n    }\n    return nil, err\n}","preventionTips":["Never pass nil context; use context.Background() for long-lived creds.","Lint for nil-context arguments in credential construction.","Thread context explicitly from a single owned root for credential lifetime."],"tags":["grpc","credentials","gcp","validation","configuration"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}