{"record":{"id":"0d3f2b3ad50ba1c2","repo":"redis/redis-py","slug":"ocsp-certificate-has-invalid-update-in-the-past","errorCode":null,"errorMessage":"ocsp certificate has invalid update - in the past","messagePattern":"ocsp certificate has invalid update - in the past","errorType":"exception","errorClass":"ConnectionError","httpStatus":null,"severity":"warning","filePath":"redis/ocsp.py","lineNumber":75,"sourceCode":"    if ocsp_response.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL:\n        if ocsp_response.certificate_status != ocsp.OCSPCertStatus.GOOD:\n            raise ConnectionError(\n                f\"Received an {str(ocsp_response.certificate_status).split('.')[1]} \"\n                \"ocsp certificate status\"\n            )\n    else:\n        raise ConnectionError(\n            \"failed to retrieve a successful response from the ocsp responder\"\n        )\n\n    if ocsp_response.this_update >= datetime.datetime.now():\n        raise ConnectionError(\"ocsp certificate was issued in the future\")\n\n    if (\n        ocsp_response.next_update\n        and ocsp_response.next_update < datetime.datetime.now()\n    ):\n        raise ConnectionError(\"ocsp certificate has invalid update - in the past\")\n\n    responder_name = ocsp_response.responder_name\n    issuer_hash = ocsp_response.issuer_key_hash\n    responder_hash = ocsp_response.responder_key_hash\n\n    cert_to_validate = issuer_cert\n    if (\n        responder_name is not None\n        and responder_name == issuer_cert.subject\n        or responder_hash == issuer_hash\n    ):\n        cert_to_validate = issuer_cert\n    else:\n        certs = ocsp_response.certificates\n        responder_certs = _get_certificates(\n            certs, issuer_cert, responder_name, responder_hash\n        )\n","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/ocsp.py#L57-L93","documentation":"Raised as a ConnectionError by _check_certificate (redis/ocsp.py:75) when next_update is present and ocsp_response.next_update < now(). The nextUpdate field is the responder's guarantee of freshness; a past nextUpdate means the response is stale and the revocation status can no longer be trusted, so redis-py rejects it.","triggerScenarios":"OCSP verification runs on a cached/stale response whose nextUpdate has passed. next_update is optional, so this only fires when the responder included it AND it is already in the past.","commonSituations":"Locally cached OCSP response not refreshed before its nextUpdate; responder outage preventing refresh while the cached copy expires; long-lived process holding a stapled response past its validity; clock skew making a valid nextUpdate appear past.","solutions":["Force a fresh OCSP fetch (drop any cached/stapled response) so the responder returns a current nextUpdate.","Synchronize the client clock to rule out skew making a valid nextUpdate appear expired.","If using OCSP stapling, ensure the server refreshes its staple frequently enough to stay ahead of nextUpdate.","Investigate responder availability if fresh fetches still return already-expired responses."],"exampleFix":"# before - stale cached OCSP response past nextUpdate\nverifier.is_valid()  # ConnectionError: ocsp certificate has invalid update - in the past\n\n# after - fetch a fresh response (no cache) and sync clock\n# 1. Clear any local OCSP cache\n# 2. Run direct validation: verifier.is_valid() fetches from the responder\n# 3. Confirm responder returns nextUpdate > now","handlingStrategy":"validation","validationCode":"import datetime\nfrom cryptography.x509 import ocsp\n\ndef ocsp_response_is_fresh(ocsp_bytes):\n    resp = ocsp.load_der_ocsp_response(ocsp_bytes)\n    if resp.next_update is None:\n        return True\n    return resp.next_update > datetime.datetime.now()","typeGuard":null,"tryCatchPattern":"from redis.exceptions import ConnectionError as RedisConnectionError\n\ntry:\n    verifier.is_valid()\nexcept RedisConnectionError as e:\n    if 'invalid update' in str(e) and 'past' in str(e):\n        logging.warning('Stale OCSP response (nextUpdate passed) - force refresh')\n    raise","preventionTips":["Do not cache OCSP responses beyond their nextUpdate; refresh proactively before expiry.","For stapling, configure the server to refresh staples on a cadence shorter than nextUpdate validity.","Sync the client clock so a valid nextUpdate is not misread as expired.","Monitor responder reachability so caches are refreshed before they go stale."],"tags":["ocsp","ssl","tls","security","stale","clock-skew","certificate","connection"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}