redis/redis-py · error · RedisError
Invalid SSL Certificate Requirements Flag: {cert_reqs}
Error message
Invalid SSL Certificate Requirements Flag: {cert_reqs} What it means
Raised as a RedisError from RedisSSLContext.__init__ when ssl_cert_reqs is passed as a string that is not one of 'none', 'optional', 'required'. These three map to ssl.CERT_NONE / CERT_OPTIONAL / CERT_REQUIRED; any other string is rejected because it cannot be translated to a VerifyMode. Numeric ssl constants pass through unchecked.
Source
Thrown at redis/asyncio/connection.py:1641
min_version: Optional[TLSVersion] = None,
ciphers: Optional[str] = None,
password: Optional[str] = None,
):
if not SSL_AVAILABLE:
raise RedisError("Python wasn't built with SSL support")
self.keyfile = keyfile
self.certfile = certfile
if cert_reqs is None:
cert_reqs = ssl.CERT_NONE
elif isinstance(cert_reqs, str):
CERT_REQS = { # noqa: N806
"none": ssl.CERT_NONE,
"optional": ssl.CERT_OPTIONAL,
"required": ssl.CERT_REQUIRED,
}
if cert_reqs not in CERT_REQS:
raise RedisError(
f"Invalid SSL Certificate Requirements Flag: {cert_reqs}"
)
cert_reqs = CERT_REQS[cert_reqs]
self.cert_reqs = cert_reqs
self.include_verify_flags = include_verify_flags
self.exclude_verify_flags = exclude_verify_flags
self.ca_certs = ca_certs
self.ca_data = ca_data
self.ca_path = ca_path
self.check_hostname = (
check_hostname if self.cert_reqs != ssl.CERT_NONE else False
)
self.min_version = min_version
self.ciphers = ciphers
self.password = password
self.context: Optional[SSLContext] = None
def get(self) -> SSLContext:View on GitHub (pinned to da03cdc7e8)
Solutions
- Use one of the exact lowercase strings: 'none', 'optional', or 'required'.
- Or pass the ssl constant directly: ssl.CERT_REQUIRED, ssl.CERT_OPTIONAL, ssl.CERT_NONE.
- Double-check URL query strings: rediss://host?ssl_cert_reqs=required (lowercase).
Example fix
// before r = redis.asyncio.Redis(host=h, port=p, ssl=True, ssl_cert_reqs="CERT_REQUIRED") // after import ssl r = redis.asyncio.Redis(host=h, port=p, ssl=True, ssl_cert_reqs=ssl.CERT_REQUIRED)
Defensive patterns
Strategy: validation
Validate before calling
import ssl
VALID_CERT_REQS = {"none", "optional", "required"}
def normalize_cert_reqs(value):
if isinstance(value, str):
if value not in VALID_CERT_REQS:
raise ValueError(f"Use one of {VALID_CERT_REQS} or an ssl.CERT_* constant")
return value Type guard
def is_valid_cert_reqs(value) -> bool:
import ssl
if isinstance(value, ssl.VerifyMode):
return True
return value in ("none", "optional", "required") Try / catch
from redis.exceptions import RedisError
try:
r = redis.asyncio.Redis(..., ssl=True, ssl_cert_reqs=req)
except RedisError as e:
if "Invalid SSL Certificate" in str(e):
r = redis.asyncio.Redis(..., ssl=True, ssl_cert_reqs="required")
else:
raise Prevention
- Pass ssl.CERT_REQUIRED/CERT_OPTIONAL/CERT_NONE directly to avoid string pitfalls.
- URL params must use the lowercase short forms.
- Validate cert_reqs in config code before constructing the client.
When it happens
Trigger: Passing ssl_cert_reqs='CERT_REQUIRED', ssl_cert_reqs='require', or any non-canonical string (case-sensitive, must be lowercase 'none'/'optional'/'required') to SSLConnection or via Redis(...)/from_url with ssl params. The lookup table at line 1635 only contains lowercase keys.
Common situations: Copying the ssl module's constant NAMES ('CERT_REQUIRED') instead of the short forms; typos like 'req'/'optional2'; mixing up with the Redis URL query param ssl_cert_reqs which forwards the string here.
Related errors
- Invalid ssl verify flag: {flag}
- Python wasn't built with SSL support
- Invalid value for '{name}' in connection URL.
- Redis URL must specify one of the following schemes ({valid_
- 'username' and 'password' cannot be passed along with 'crede
AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04).
Data as JSON: /data/errors/9691f4d600d4ba86.json.
Report an issue: GitHub.