grpc/grpc-go · error
requires SecurityLevel %v; connection has %v
Error message
requires SecurityLevel %v; connection has %v
What it means
Returned by credentials.CheckSecurityLevel when the established connection's CommonAuthInfo.SecurityLevel is below the requested level (credentials.go:302). Levels are ordered NoSecurity < IntegrityOnly < PrivacyAndIntegrity. It is the guard per-RPC credential implementations use to refuse sending secrets over an insufficiently protected transport.
Source
Thrown at credentials/credentials.go:303
// 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.
type ChannelzSecurityInfo interface {
GetSecurityValue() ChannelzSecurityValue
}
// ChannelzSecurityValue defines the interface that GetSecurityValue() return value
// should satisfy. This interface should only be satisfied by *TLSChannelzSecurityValue
// and *OtherChannelzSecurityValue.
//View on GitHub (pinned to 03255a9237)
Solutions
- Use TLS or ALTS transport credentials on the channel so AuthInfo.SecurityLevel >= PrivacyAndIntegrity.
- If using a custom TransportCredentials, embed CommonAuthInfo{SecurityLevel: PrivacyAndIntegrity} in the returned AuthInfo.
- For local dev where TLS is not possible, do not attach per-RPC credentials that RequireTransportSecurity().
- Call CheckSecurityLevel yourself with the exact level you need to fail fast with a clearer message.
Example fix
// before: per-RPC creds over insecure transport
conn, _ := grpc.NewClient(addr,
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithPerRPCCredentials(tokenCreds),
)
// after: TLS so security level satisfies PrivacyAndIntegrity
conn, _ := grpc.NewClient(addr,
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithPerRPCCredentials(tokenCreds),
) Defensive patterns
Strategy: validation
Validate before calling
// Verify the security level before relying on the connection.
if err := credentials.CheckSecurityLevel(authInfo, credentials.PrivacyAndIntegrity); err != nil {
return fmt.Errorf("channel is not sufficiently secure: %w", err)
} Type guard
// Confirm AuthInfo carries a usable CommonAuthInfo.
func hasSecurityLevel(ai credentials.AuthInfo) bool {
type common interface{ GetCommonAuthInfo() credentials.CommonAuthInfo }
c, ok := ai.(common)
return ok && c.GetCommonAuthInfo().SecurityLevel >= credentials.PrivacyAndIntegrity
} Try / catch
if err := credentials.CheckSecurityLevel(ri.AuthInfo, want); err != nil {
// configuration error, not transient: fix the channel's transport credentials.
return fmt.Errorf("refusing to send credentials: %w", err)
} Prevention
- Always pair security-requiring per-RPC creds with TLS or ALTS transport.
- Set SecurityLevel correctly in custom TransportCredentials AuthInfo.
- Never use insecure.NewCredentials() with creds whose RequireTransportSecurity() is true.
- Call CheckSecurityLevel yourself to fail with a clear message at startup.
When it happens
Trigger: A PerRPCCredentials implementation calls CheckSecurityLevel(ai, PrivacyAndIntegrity) but the channel was built with insecure.NewCredentials() (NoSecurity) or an integrity-only scheme. The AuthInfo embedded a SecurityLevel below the required one. Also reachable directly from user code calling CheckSecurityLevel on server-side AuthInfo.
Common situations: Using oauth/JWT/ALTS per-RPC credentials on a grpc.WithTransportCredentials(insecure.NewCredentials()) channel; mixing a TLS-requiring call cred with a plaintext dev channel; or a custom TransportCredentials whose AuthInfo forgot to set SecurityLevel to PrivacyAndIntegrity.
Related errors
- credentials: cannot send secure credentials on an insecure c
- credentials: ctx cannot be nil
- credentials: audience cannot be empty
- credentials: failed to create ID token credentials: %v
- unsupported mode: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/675f42d49c5a0d1d.
Report an issue: GitHub.