{"record":{"id":"cf7607f72f47cd8e","repo":"redis/redis-py","slug":"received-and-expected-certificates-do-not-match","errorCode":null,"errorMessage":"received and expected certificates do not match","messagePattern":"received and expected certificates do not match","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"critical","filePath":"redis/ocsp.py","lineNumber":165,"sourceCode":"    \"\"\"\n    if ocsp_bytes in [b\"\", None]:\n        raise ConnectionError(\"no ocsp response present\")\n\n    issuer_cert = None\n    peer_cert = con.get_peer_certificate().to_cryptography()\n    for c in con.get_peer_cert_chain():\n        cert = c.to_cryptography()\n        if cert.subject == peer_cert.issuer:\n            issuer_cert = cert\n            break\n\n    if issuer_cert is None:\n        raise ConnectionError(\"no matching issuer cert found in certificate chain\")\n\n    if expected is not None:\n        e = x509.load_pem_x509_certificate(expected)\n        if peer_cert != e:\n            raise ConnectionError(\"received and expected certificates do not match\")\n\n    return _check_certificate(issuer_cert, ocsp_bytes)\n\n\nclass OCSPVerifier:\n    \"\"\"A class to verify ssl sockets for RFC6960/RFC6961. This can be used\n    when using direct validation of OCSP responses and certificate revocations.\n\n    @see https://datatracker.ietf.org/doc/html/rfc6960\n    @see https://datatracker.ietf.org/doc/html/rfc6961\n    \"\"\"\n\n    def __init__(self, sock, host, port, ca_certs=None):\n        self.SOCK = sock\n        self.HOST = host\n        self.PORT = port\n        self.CA_CERTS = ca_certs\n","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/ocsp.py#L147-L183","documentation":"Raised as a ConnectionError by ocsp_staple_verifier (redis/ocsp.py:165) when an `expected` certificate is supplied (pinned-cert mode) and the server's peer certificate does not match it. The function loads expected via x509.load_pem_x509_certificate and compares peer_cert != e; any mismatch aborts. This is an explicit pinning check — the caller asserted which cert should be present and the server presented a different one.","triggerScenarios":"Calling ocsp_staple_verifier(con, ocsp_bytes, expected=<pinned_cert_bytes>) where the server presents a different certificate than the pinned one. Common when the pinned cert was rotated and the client's expected value is stale, or when connecting to the wrong endpoint that serves a different cert.","commonSituations":"Certificate rotated on the server but the client's pinned expected cert not updated; connecting to a different node/region that uses a distinct cert; MITM presenting an attacker cert; pin file path points at an old cert; cert reissued with the same subject but different key/serial.","solutions":["Update the pinned expected certificate to the server's current certificate if the rotation was legitimate.","Confirm you are connecting to the intended endpoint (host/port) whose cert matches the pin.","If the mismatch is unexpected, treat it as a possible MITM and investigate before trusting the new cert.","Automate pin rotation so server and client pins are updated together to avoid stale-pin failures."],"exampleFix":"# before - pinned expected cert is stale after rotation\nocsp_staple_verifier(con, ocsp_bytes, expected=old_cert_pem)  # ConnectionError: received and expected certificates do not match\n\n# after - update the pin to the new server cert (after validating the rotation is legitimate)\nocsp_staple_verifier(con, ocsp_bytes, expected=new_cert_pem)","handlingStrategy":"try-catch","validationCode":"from cryptography import x509\n\ndef peer_matches_pinned_cert(con, expected_pem):\n    peer = con.get_peer_certificate().to_cryptography()\n    expected = x509.load_pem_x509_certificate(expected_pem)\n    return peer == expected","typeGuard":null,"tryCatchPattern":"from redis.exceptions import ConnectionError as RedisConnectionError\n\ntry:\n    ocsp_staple_verifier(con, ocsp_bytes, expected=pin)\nexcept RedisConnectionError as e:\n    if 'do not match' in str(e):\n        logging.critical('Peer cert does not match pinned cert - possible MITM or rotation: %s', e)\n    raise","preventionTips":["Update the pinned expected certificate whenever the server cert is legitimately rotated.","Investigate unexpected pin mismatches as possible MITM before trusting the new cert.","Automate coordinated pin rotation between server and client to avoid stale-pin failures.","Confirm host/port before pin comparison to avoid cross-region cert mismatches."],"tags":["ocsp","ssl","tls","security","certificate-pinning","certificate","connection"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}