grpc/grpc-go · error

AuthInfo is nil

Error message

AuthInfo is nil

What it means

Returned by credentials.CheckSecurityLevel when the AuthInfo argument is nil. This function is typically called by PerRPCCredentials implementations (e.g., STS, oauth) via credentials.RequestInfoFromContext to verify the connection meets a minimum security level before attaching per-RPC credentials. A nil AuthInfo means the request context has no security information, usually because the RPC was made over an insecure channel or the credentials were invoked outside a real RPC.

Solutions

  1. Ensure the channel uses TLS or another transport security mechanism so that AuthInfo is populated.
  2. In unit tests, build the context with credentials.NewContextWithRequestInfo(ctx, credentials.RequestInfo{AuthInfo: ...}) to simulate a secured connection.
  3. If the service genuinely allows insecure connections, skip CheckSecurityLevel or handle the nil-AuthInfo case explicitly before calling it.

Example fix

// before
creds := &oauth.TokenSource{TokenSource: ts}
conn, _ := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithPerRPCCredentials(creds)) // AuthInfo is nil
// after
conn, _ := grpc.Dial(addr, grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)), grpc.WithPerRPCCredentials(creds))
Defensive patterns

Strategy: validation

Validate before calling

// Before CheckSecurityLevel, verify AuthInfo is populated:
ri, ok := credentials.RequestInfoFromContext(ctx)
if !ok || ri.AuthInfo == nil {
    return status.Error(codes.Unauthenticated, "no security info; use a secure channel")
}
if err := credentials.CheckSecurityLevel(ri.AuthInfo, credentials.PrivacyAndIntegrity); err != nil {
    return err
}

Type guard

func hasAuthInfo(ctx context.Context) bool {
    ri, ok := credentials.RequestInfoFromContext(ctx)
    return ok && ri.AuthInfo != nil
}

Try / catch

if err := credentials.CheckSecurityLevel(ri.AuthInfo, level); err != nil {
    if ri.AuthInfo == nil {
        // channel lacks transport security; upgrade to TLS
    }
    return err
}

Prevention

When it happens

Trigger: A PerRPCCredentials.GetRequestMetadata implementation calls credentials.CheckSecurityLevel(ri.AuthInfo, ...) where ri.AuthInfo is nil. This happens when the channel uses insecure.NewCredentials (no transport security), when RequestInfo was not populated (custom invocation outside gRPC), or in unit tests that call GetRequestMetadata with a bare context.

Common situations: Developers attach per-RPC credentials (like OAuth tokens) to an insecure channel, or test GetRequestMetadata without using credentials.NewContextWithRequestInfo. Also occurs when a custom call-credential implementation is invoked on a stream that bypassed the normal transport handshake.

Related errors


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

Appendix: source

Thrown at credentials/credentials.go:295

// in ctx.
//
// This API is experimental.
func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo {
	chi, _ := icredentials.ClientHandshakeInfoFromContext(ctx).(ClientHandshakeInfo)
	return chi
}

// CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one.
// It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method
// or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility.
//
// This API is experimental.
func CheckSecurityLevel(ai AuthInfo, level SecurityLevel) error {
	type internalInfo interface {
		GetCommonAuthInfo() CommonAuthInfo
	}
	if ai == nil {
		return errors.New("AuthInfo is nil")
	}
	if ci, ok := ai.(internalInfo); ok {
		// CommonAuthInfo.SecurityLevel has an invalid value.
		if ci.GetCommonAuthInfo().SecurityLevel == InvalidSecurityLevel {
			return nil
		}
		if ci.GetCommonAuthInfo().SecurityLevel < level {
			return fmt.Errorf("requires SecurityLevel %v; connection has %v", level, ci.GetCommonAuthInfo().SecurityLevel)
		}
	}
	// The condition is satisfied or AuthInfo struct does not implement GetCommonAuthInfo() method.
	return nil
}

// ChannelzSecurityInfo defines the interface that security protocols should implement
// in order to provide security info to channelz.
//
// This API is experimental.

View on GitHub (pinned to 0c51461d27)