Skip to content
ecdsa.com
Python 3.13+ ssl modulePython cryptography

Error message

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical

Only clients that enable strict checking print this: Python 3.13 and later by default, and openssl verify -x509_strict. Python adds a source location such as "(_ssl.c:1082)".

Python 3.13+ ssl module — VERIFY_X509_STRICT in create_default_context(), X509_V_ERR_CA_BCONS_NOT_CRITICAL

What it means

Python 3.13+ verifies with OpenSSL's strict X.509 mode, which enforces RFC 5280's rule that a CA certificate's basicConstraints extension must be marked critical. The CA in your chain has basicConstraints CA:TRUE without the critical flag, so OpenSSL rejects the chain even though the CA is trusted.

Why it happens

How to fix it

  1. 1.

    Find the non-compliant certificate

    Print basicConstraints for each CA in the chain; the one without "critical" must be reissued. openssl verify -x509_strict shows all strict-mode problems.

    bash
    openssl x509 -in ca.pem -noout -ext basicConstraints
    # X509v3 Basic Constraints:            <- no "critical" here is the problem
    #     CA:TRUE
    openssl verify -x509_strict -CAfile ca.pem server.pem
  2. 2.

    Reissue the CA with critical basicConstraints

    Re-sign the CA certificate with basicConstraints = critical, CA:TRUE and a keyUsage extension. Keeping the same key and subject lets existing certificates verify against it.

    bash
    openssl req -x509 -new -key ca.key -days 3650 -subj "/CN=Example Private CA" \
      -addext "basicConstraints=critical,CA:TRUE" \
      -addext "keyUsage=critical,keyCertSign,cRLSign" \
      -out ca.pem
  3. 3.

    Temporary workaround: clear VERIFY_X509_STRICT

    Restores the pre-3.13 behaviour for one context while the CA is fixed. Verification of the chain, validity dates and host name stays on.

    python
    # Temporary workaround until the CA is reissued (chain, dates and name are still checked)
    import ssl
    ctx = ssl.create_default_context(cafile="ca.pem")
    ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT

Related errors

Browse the full signature error database