redis/redis-py · error · ConnectionError
no issuers found in certificate chain
Error message
no issuers found in certificate chain
What it means
Raised by OCSPValidator.is_valid() (redis/ocsp.py:302) during client-side OCSP revocation checking. After reading the peer certificate off the already-wrapped TLS socket via components_from_socket(), the code extracts the CA Issuers URL from the certificate's Authority Information Access (AIA) extension; if no CA_ISSUERS entry exists (IndexError caught at ocsp.py:226-227 sets issuer=None), redis-py cannot download the issuer certificate required to build an OCSP request, so it aborts with ConnectionError. The server certificate must carry an AIA extension with a reachable CA Issuers URI for OCSP validation to proceed.
Solutions
- Provision a server certificate whose AIA extension includes an http(s) CA Issuers URL pointing to the issuer's DER-encoded certificate.
- Regenerate the cert with AIA, e.g. `openssl x509 -req ... -extfile <(printf 'authorityInfoAccess=CA Issuers;URI:https://ca.example.com/issuer.cer')`.
- If OCSP revocation checking is not required for your deployment, drop the OCSPValidator / ssl_ocsp_context from the client config.
- As a last resort set ssl_cert_reqs=ssl.CERT_NONE ONLY if you fully understand the security implications (NOT recommended for production).
Example fix
# before: cert has no AIA -> ConnectionError: no issuers found in certificate chain r = redis.Redis(host=..., ssl=True, ssl_ocsp_context=ocsp_ctx) # after (option A): server cert regenerated with AIA CA Issuers URI # (server-side change, no client edit needed) # after (option B): disable OCSP validation if not required r = redis.Redis(host=..., ssl=True, ssl_cert_reqs="required")
Defensive patterns
Strategy: validation
Validate before calling
from cryptography import x509
from cryptography.x509.oid import ExtensionOID, AuthorityInformationAccessOID
def cert_has_issuer_url(pem_bytes: bytes) -> bool:
cert = x509.load_pem_x509_certificate(pem_bytes)
try:
aia = cert.extensions.get_extension_for_oid(
ExtensionOID.AUTHORITY_INFORMATION_ACCESS
).value
except x509.ExtensionNotFound:
return False
return any(
ext.access_method == AuthorityInformationAccessOID.CA_ISSUERS
for ext in aia
)
# run BEFORE enabling OCSP:
# assert cert_has_issuer_url(server_pem), 'cert lacks AIA CA Issuers URL' Type guard
from cryptography import x509
from cryptography.x509.oid import ExtensionOID, AuthorityInformationAccessOID
def has_reachable_aia_issuer(cert) -> bool:
try:
aia = cert.extensions.get_extension_for_oid(
ExtensionOID.AUTHORITY_INFORMATION_ACCESS
).value
except x509.ExtensionNotFound:
return False
return any(
e.access_method == AuthorityInformationAccessOID.CA_ISSUERS
and str(e.access_location.value).startswith(('http://', 'https://'))
for e in aia
) Try / catch
import redis
try:
client = redis.Redis(host=..., ssl=True, ssl_ocsp_context=ctx)
client.ping()
except redis.ConnectionError as e:
if 'no issuers found in certificate chain' in str(e):
# server cert lacks AIA CA Issuers URL; disable OCSP or reissue cert
... Prevention
- Generate all TLS certs with an AIA extension pointing to a reachable CA Issuers URI.
- Validate certs in CI with a script that asserts has_reachable_aia_issuer() before deploying.
- Keep OCSP validation off for dev/test unless your test CA publishes AIA and OCSP endpoints.
When it happens
Trigger: Constructing a client with OCSP validation enabled (e.g. ssl=True plus an OCSPValidator / ssl_ocsp_context) against a Redis server whose TLS certificate has no AIA extension, an AIA extension without a CA_ISSUERS access method, or a CA_ISSUERS entry whose access_location is empty. Specifically, components_from_socket() returns (cert, None, ocsp_server) and the `if issuer_url is None` branch at ocsp.py:301 fires.
Common situations: Self-signed or internally-issued certificates that omit AIA; private CAs that do not publish an AIA URI; stunnel or a TLS-terminating proxy presenting a cert without OCSP/AIA info; test certificates generated with plain `openssl req -x509` and no AIA extension.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- delegate not authorized for ocsp signing
- failed to fetch issuer certificate
- failed to fetch ocsp certificate
- failed to retrieve a successful response from the ocsp…
- failed to valid ocsp response
AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10).
Data as JSON: /api/errors/621315f399c07121.
Report an issue: GitHub.
Appendix: source
Thrown at redis/ocsp.py:302
}
r = requests.get(ocsp_url, headers=header)
if not r.ok:
raise ConnectionError("failed to fetch ocsp certificate")
return _check_certificate(issuer_cert, r.content, True)
def is_valid(self):
"""Returns the validity of the certificate wrapping our socket.
This first retrieves for validate the certificate, issuer_url,
and ocsp_server for certificate validate. Then retrieves the
issuer certificate from the issuer_url, and finally checks
the validity of OCSP revocation status.
"""
# validate the certificate
try:
cert, issuer_url, ocsp_server = self.components_from_socket()
if issuer_url is None:
raise ConnectionError("no issuers found in certificate chain")
return self.check_certificate(ocsp_server, cert, issuer_url)
except AuthorizationError:
cert, issuer_url, ocsp_server = self.components_from_direct_connection()
if issuer_url is None:
raise ConnectionError("no issuers found in certificate chain")
return self.check_certificate(ocsp_server, cert, issuer_url)
View on GitHub (pinned to 6a6b581b48)