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

  1. Provision a server certificate whose AIA extension includes an http(s) CA Issuers URL pointing to the issuer's DER-encoded certificate.
  2. Regenerate the cert with AIA, e.g. `openssl x509 -req ... -extfile <(printf 'authorityInfoAccess=CA Issuers;URI:https://ca.example.com/issuer.cer')`.
  3. If OCSP revocation checking is not required for your deployment, drop the OCSPValidator / ssl_ocsp_context from the client config.
  4. 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

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

Related errors


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)