redis/redis-py · warning · ConnectionError

ocsp certificate was issued in the future

Error message

ocsp certificate was issued in the future

What it means

Raised as a ConnectionError by _check_certificate (redis/ocsp.py:69) when ocsp_response.this_update >= datetime.datetime.now(). The thisUpdate field is when the responder asserts the status; a value in the future is invalid per RFC 6960 and indicates either clock skew between client and responder or a tampered/misconfigured response.

Solutions

  1. Synchronize the client clock (NTP/chrony) and retry — client clock drift is the most common cause.
  2. Verify the responder's time source if the client clock is correct and the issue persists.
  3. Inspect ocsp_response.this_update and compare to a trusted time source to determine whether the response or the clock is wrong.
  4. Do not silently accept a future-dated response; treat persistent future timestamps as a trust failure.

Example fix

# before - client clock drifted, OCSP thisUpdate appears 'in the future'
verifier.is_valid()  # ConnectionError: ocsp certificate was issued in the future

# after - sync the clock, then retry
# (run) ntpdate / chronyc makestep  OR  systemd-timesyncd restart
verifier.is_valid()  # now thisUpdate < now, verification proceeds
Defensive patterns

Strategy: validation

Validate before calling

import datetime, ntplib

def clock_synced(max_offset_seconds=60):
    try:
        resp = ntplib.NTPClient().request('pool.ntp.org', timeout=2)
        return abs(resp.offset) < max_offset_seconds
    except Exception:
        return False  # cannot confirm - do not bypass OCSP on this basis

Try / catch

from redis.exceptions import ConnectionError as RedisConnectionError

try:
    verifier.is_valid()
except RedisConnectionError as e:
    if 'issued in the future' in str(e):
        logging.warning('OCSP thisUpdate in future - check client NTP sync: %s', e)
    raise

Prevention

When it happens

Trigger: OCSP verification runs and the response's thisUpdate timestamp is at or after the client's current wall clock. Triggered by NTP drift on the client, a responder with a wrong clock, or a forged response with a future-dated thisUpdate.

Common situations: Client clock behind real time (no NTP sync); container/VM with drifted clock after suspend/resume; responder clock ahead; deliberate forgery attempting to extend apparent validity; timezone mishandling producing naive-vs-aware datetime comparisons.

Understand the failure class

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/738637536252327b. Report an issue: GitHub.

Appendix: source

Thrown at redis/ocsp.py:69

    """A wrapper the return the validity of a known ocsp certificate"""

    ocsp_response = ocsp.load_der_ocsp_response(ocsp_bytes)

    if ocsp_response.response_status == ocsp.OCSPResponseStatus.UNAUTHORIZED:
        raise AuthorizationError("you are not authorized to view this ocsp certificate")
    if ocsp_response.response_status == ocsp.OCSPResponseStatus.SUCCESSFUL:
        if ocsp_response.certificate_status != ocsp.OCSPCertStatus.GOOD:
            raise ConnectionError(
                f"Received an {str(ocsp_response.certificate_status).split('.')[1]} "
                "ocsp certificate status"
            )
    else:
        raise ConnectionError(
            "failed to retrieve a successful response from the ocsp responder"
        )

    if ocsp_response.this_update >= datetime.datetime.now():
        raise ConnectionError("ocsp certificate was issued in the future")

    if (
        ocsp_response.next_update
        and ocsp_response.next_update < datetime.datetime.now()
    ):
        raise ConnectionError("ocsp certificate has invalid update - in the past")

    responder_name = ocsp_response.responder_name
    issuer_hash = ocsp_response.issuer_key_hash
    responder_hash = ocsp_response.responder_key_hash

    cert_to_validate = issuer_cert
    if (
        responder_name is not None
        and responder_name == issuer_cert.subject
        or responder_hash == issuer_hash
    ):
        cert_to_validate = issuer_cert

View on GitHub (pinned to 6a6b581b48)