grpc/grpc-go · error

AuthInfo is nil

Error message

AuthInfo is nil

What it means

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.

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 03255a9237)

Solutions

  1. Null-check AuthInfo before calling CheckSecurityLevel: if p.AuthInfo == nil { return Unauthenticated }.
  2. Ensure the connection actually completed a handshake so AuthInfo is populated (use real or fake non-nil creds in tests).
  3. For insecure connections, pass an AuthInfo whose CommonAuthInfo.SecurityLevel is intentionally set (or accept the nil check as a denial).
  4. Treat a nil AuthInfo as a security failure (deny) rather than letting the helper error propagate raw.

Example fix

// before — passes possibly-nil AuthInfo straight to the helper
p, _ := peer.FromContext(ctx)
if err := credentials.CheckSecurityLevel(p.AuthInfo, credentials.PrivacyAndIntegrity); err != nil {
    return err // 'AuthInfo is nil' leaks to caller
}

// after — guard nil first and deny cleanly
p, ok := peer.FromContext(ctx)
if !ok || p.AuthInfo == nil {
    return status.Error(codes.Unauthenticated, "missing auth info")
}
if err := credentials.CheckSecurityLevel(p.AuthInfo, credentials.PrivacyAndIntegrity); err != nil {
    return status.Error(codes.PermissionDenied, err.Error())
}
Defensive patterns

Strategy: validation

Validate before calling

// Null-check AuthInfo before calling CheckSecurityLevel
func requireLevel(ctx context.Context, lvl credentials.SecurityLevel) error {
    p, ok := peer.FromContext(ctx)
    if !ok || p.AuthInfo == nil {
        return status.Error(codes.Unauthenticated, "missing auth info")
    }
    return credentials.CheckSecurityLevel(p.AuthInfo, lvl)
}

Type guard

func hasAuthInfo(p *peer.Peer) bool {
    return p != nil && p.AuthInfo != nil
}

Try / catch

if err := credentials.CheckSecurityLevel(ai, lvl); err != nil {
    if strings.Contains(err.Error(), "AuthInfo is nil") {
        return status.Error(codes.Unauthenticated, "no auth info")
    }
    return status.Error(codes.PermissionDenied, err.Error())
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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