{"id":"9691f4d600d4ba86","repo":"redis/redis-py","slug":"invalid-ssl-certificate-requirements-flag-cert-r","errorCode":null,"errorMessage":"Invalid SSL Certificate Requirements Flag: {cert_reqs}","messagePattern":"Invalid SSL Certificate Requirements Flag: (.+?)","errorType":"validation","errorClass":"RedisError","httpStatus":null,"severity":"error","filePath":"redis/asyncio/connection.py","lineNumber":1641,"sourceCode":"        min_version: Optional[TLSVersion] = None,\n        ciphers: Optional[str] = None,\n        password: Optional[str] = None,\n    ):\n        if not SSL_AVAILABLE:\n            raise RedisError(\"Python wasn't built with SSL support\")\n\n        self.keyfile = keyfile\n        self.certfile = certfile\n        if cert_reqs is None:\n            cert_reqs = ssl.CERT_NONE\n        elif isinstance(cert_reqs, str):\n            CERT_REQS = {  # noqa: N806\n                \"none\": ssl.CERT_NONE,\n                \"optional\": ssl.CERT_OPTIONAL,\n                \"required\": ssl.CERT_REQUIRED,\n            }\n            if cert_reqs not in CERT_REQS:\n                raise RedisError(\n                    f\"Invalid SSL Certificate Requirements Flag: {cert_reqs}\"\n                )\n            cert_reqs = CERT_REQS[cert_reqs]\n        self.cert_reqs = cert_reqs\n        self.include_verify_flags = include_verify_flags\n        self.exclude_verify_flags = exclude_verify_flags\n        self.ca_certs = ca_certs\n        self.ca_data = ca_data\n        self.ca_path = ca_path\n        self.check_hostname = (\n            check_hostname if self.cert_reqs != ssl.CERT_NONE else False\n        )\n        self.min_version = min_version\n        self.ciphers = ciphers\n        self.password = password\n        self.context: Optional[SSLContext] = None\n\n    def get(self) -> SSLContext:","sourceCodeStart":1623,"sourceCodeEnd":1659,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/asyncio/connection.py#L1623-L1659","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nr = redis.asyncio.Redis(host=h, port=p, ssl=True, ssl_cert_reqs=\"CERT_REQUIRED\")\n\n// after\nimport ssl\nr = redis.asyncio.Redis(host=h, port=p, ssl=True, ssl_cert_reqs=ssl.CERT_REQUIRED)","handlingStrategy":"validation","validationCode":"import ssl\nVALID_CERT_REQS = {\"none\", \"optional\", \"required\"}\ndef normalize_cert_reqs(value):\n    if isinstance(value, str):\n        if value not in VALID_CERT_REQS:\n            raise ValueError(f\"Use one of {VALID_CERT_REQS} or an ssl.CERT_* constant\")\n    return value","typeGuard":"def is_valid_cert_reqs(value) -> bool:\n    import ssl\n    if isinstance(value, ssl.VerifyMode):\n        return True\n    return value in (\"none\", \"optional\", \"required\")","tryCatchPattern":"from redis.exceptions import RedisError\ntry:\n    r = redis.asyncio.Redis(..., ssl=True, ssl_cert_reqs=req)\nexcept RedisError as e:\n    if \"Invalid SSL Certificate\" in str(e):\n        r = redis.asyncio.Redis(..., ssl=True, ssl_cert_reqs=\"required\")\n    else:\n        raise","preventionTips":["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."],"tags":["ssl","config","validation","tls","async"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}