grpc/grpc-go · error

credentials: ctx cannot be nil

Error message

credentials: ctx cannot be nil

What it means

Returned by google.NewServiceAccountIdentityCredentials when the ctx argument is nil. The constructor stores ctx to drive background token fetches for the credential's lifetime, so a nil context would panic later; the function validates upfront and returns this error instead.

Solutions

  1. Pass a non-cancellation context scoped to the credential's lifetime, e.g. context.Background() or a context you cancel on shutdown.
  2. Do not pass an RPC-scoped context (the doc explicitly warns against it); use a long-lived context.
  3. Add a unit test asserting ctx != nil before calling the constructor.

Example fix

// before
creds, err := google.NewServiceAccountIdentityCredentials(nil, aud) // error

// after
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
creds, err := google.NewServiceAccountIdentityCredentials(ctx, aud)
Defensive patterns

Strategy: validation

Validate before calling

func newCredsSafe(ctx context.Context, audience string) (credentials.PerRPCCredentials, error) {
    if ctx == nil {
        ctx = context.Background() // or return an explicit error
    }
    return google.NewServiceAccountIdentityCredentials(ctx, audience)
}

Type guard

func isContextValid(ctx context.Context) bool { return ctx != nil }

Prevention

When it happens

Trigger: Calling google.NewServiceAccountIdentityCredentials(nil, "audience"). The check at gcp_service_account_identity_credentials.go:98-100 returns the error immediately before any GCP/metadata interaction.

Common situations: Passing nil by mistake (e.g. a variable that was never initialized); refactoring that removed the context parameter sourcing; tests that construct credentials without setting up a context; code that assumed a default background context would be used (it is not — you must pass context.Background() explicitly).

Related errors


AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11). Data as JSON: /api/errors/a9dfbcb8b6989341. Report an issue: GitHub.

Appendix: source

Thrown at credentials/google/gcp_service_account_identity_credentials.go:99

// audience.
//
// This credential fetches the ID token from the GCE metadata server and is
// only valid for use in environments running on GCP. The ctx and audience
// parameters cannot be empty.
//
// The credentials object starts asynchronous background token fetches to
// refresh expired tokens. The provided context propagates cancellation to
// these background tasks. Users should not pass an RPC-scoped context here,
// but rather a context that is valid for the entire lifetime of the
// credentials and should cancel the context when they are done.
//
// # Experimental
//
// Notice: This API is EXPERIMENTAL and may be changed or removed in a
// later release.
func NewServiceAccountIdentityCredentials(ctx context.Context, audience string) (credentials.PerRPCCredentials, error) {
	if ctx == nil {
		return nil, fmt.Errorf("credentials: ctx cannot be nil")
	}

	if audience == "" {
		return nil, fmt.Errorf("credentials: audience cannot be empty")
	}

	creds, err := internal.NewIDTokenCredentials(&idtoken.Options{Audience: audience})
	if err != nil {
		return nil, fmt.Errorf("credentials: failed to create ID token credentials: %v", err)
	}

	return &gcpServiceAccountIdentityCallCreds{
		ctx:      ctx,
		audience: audience,
		creds:    creds,
		backoff:  internal.BackoffStrategy,
	}, nil
}

View on GitHub (pinned to 0c51461d27)