{"record":{"id":"c5abbe61137089e8","repo":"redis/redis-py","slug":"no-certificate-found-for-ssl-peer","errorCode":null,"errorMessage":"no certificate found for ssl peer","messagePattern":"no certificate found for ssl peer","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"error","filePath":"redis/ocsp.py","lineNumber":199,"sourceCode":"        self.PORT = port\n        self.CA_CERTS = ca_certs\n\n    def _bin2ascii(self, der):\n        \"\"\"Convert SSL certificates in a binary (DER) format to ASCII PEM.\"\"\"\n\n        pem = ssl.DER_cert_to_PEM_cert(der)\n        cert = x509.load_pem_x509_certificate(pem.encode(), backends.default_backend())\n        return cert\n\n    def components_from_socket(self):\n        \"\"\"This function returns the certificate, primary issuer, and primary ocsp\n        server in the chain for a socket already wrapped with ssl.\n        \"\"\"\n\n        # convert the binary certificate to text\n        der = self.SOCK.getpeercert(True)\n        if der is False:\n            raise ConnectionError(\"no certificate found for ssl peer\")\n        cert = self._bin2ascii(der)\n        return self._certificate_components(cert)\n\n    def _certificate_components(self, cert):\n        \"\"\"Given an SSL certificate, retract the useful components for\n        validating the certificate status with an OCSP server.\n\n        Args:\n            cert ([bytes]): A PEM encoded ssl certificate\n        \"\"\"\n\n        try:\n            aia = cert.extensions.get_extension_for_oid(\n                x509.oid.ExtensionOID.AUTHORITY_INFORMATION_ACCESS\n            ).value\n        except cryptography.x509.extensions.ExtensionNotFound:\n            raise ConnectionError(\"No AIA information present in ssl certificate\")\n","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/ocsp.py#L181-L217","documentation":"Raised as a ConnectionError by OCSPVerifier.components_from_socket (redis/ocsp.py:199) when self.SOCK.getpeercert(True) returns False, meaning the SSL socket has no peer certificate available. getpeercert(binary_form=True) returns False when the handshake hasn't completed, no cert was provided by the peer, or the socket is not actually TLS-wrapped. Without the peer cert, OCSP validation cannot start.","triggerScenarios":"Calling OCSPVerifier(sock, host, port).is_valid() (or components_from_socket directly) on a socket where getpeercert(True) returns False. Happens if the socket isn't wrapped in an SSLContext, the TLS handshake hasn't finished, or the server sent no certificate (e.g. anonymous cipher).","commonSituations":"Passing a plain (non-SSL) socket to OCSPVerifier; calling components_from_socket before the handshake completes; server misconfigured to use an anonymous/non-cipher TLS suite; TLS stripped by a proxy so the client socket sees plaintext; verification attempted on a re-used socket whose TLS state is gone.","solutions":["Ensure the socket passed to OCSPVerifier is an SSLSocket from a completed TLS handshake (wrap with SSLContext and complete the handshake before verifying).","Confirm the server actually presents a certificate (test with openssl s_client).","Do not call components_from_socket before handshake completion; perform the verify step after connect().","Verify no proxy/LB is terminating TLS before the client socket."],"exampleFix":"# before - raw socket handed to OCSPVerifier, no TLS\nverifier = OCSPVerifier(raw_sock, host, port)\nverifier.is_valid()  # ConnectionError: no certificate found for ssl peer\n\n# after - wrap in SSLContext and complete handshake first\nctx = ssl.create_default_context()\nssl_sock = ctx.wrap_socket(raw_sock, server_hostname=host)\nverifier = OCSPVerifier(ssl_sock, host, port)\nverifier.is_valid()","handlingStrategy":"validation","validationCode":"import ssl\n\ndef socket_has_peer_cert(sock):\n    return isinstance(sock, ssl.SSLSocket) and bool(sock.getpeercert(True))","typeGuard":"def is_tls_socket_with_peer_cert(sock) -> bool:\n    import ssl\n    return isinstance(sock, ssl.SSLSocket) and sock.getpeercert(True) not in (False, None, b'')","tryCatchPattern":"from redis.exceptions import ConnectionError as RedisConnectionError\n\ntry:\n    verifier.is_valid()\nexcept RedisConnectionError as e:\n    if 'no certificate found for ssl peer' in str(e):\n        logging.error('Socket has no peer cert - wrap in SSLContext and complete handshake first')\n    raise","preventionTips":["Always wrap the socket in an SSLContext and complete the TLS handshake before constructing an OCSPVerifier.","Confirm the server presents a certificate via openssl s_client before relying on OCSP verification.","Do not reuse sockets whose TLS state has been torn down.","Ensure no proxy terminates TLS in front of the client socket."],"tags":["ocsp","ssl","tls","security","handshake","certificate","connection"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}