Error message
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier
Shown by Python 3.13 and later (strict mode is on by default) and by 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_MISSING_AUTHORITY_KEY_IDENTIFIER
What it means
Python 3.13+ runs OpenSSL's strict X.509 checks, and RFC 5280 requires certificates issued by a CA to carry an authorityKeyIdentifier extension that names the issuer's key. A certificate in your chain lacks it, so verification fails although the signature and the trust anchor are fine.
Why it happens
The issuing tool does not add key identifiers
commonHand-written OpenSSL extension files, some scripts and older internal CA software issue certificates without authorityKeyIdentifier (often without subjectKeyIdentifier too).
The client was upgraded to Python 3.13+
commonPython 3.12 and older did not apply strict checks, so these certificates used to work.
Long-lived certificates from an earlier PKI setup
occasionalDevice and service certificates issued years ago, before the profile was fixed, remain in use until they expire.
How to fix it
- 1.
Confirm the missing extension
Print the key identifier extensions of the leaf and intermediates, and run openssl verify -x509_strict to list every strict-mode issue.
bash openssl x509 -in server.pem -noout -ext authorityKeyIdentifier,subjectKeyIdentifier openssl verify -x509_strict -CAfile ca.pem server.pem - 2.
Reissue certificates with key identifiers
Add subjectKeyIdentifier = hash and authorityKeyIdentifier = keyid:always to the issuing profile, then reissue the affected certificates.
bash # Issue leaves with both key identifiers printf 'subjectKeyIdentifier=hash\nauthorityKeyIdentifier=keyid:always\nsubjectAltName=DNS:api.example.com\n' > leaf.ext openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -days 90 -extfile leaf.ext -out server.pem - 3.
Temporary workaround: clear VERIFY_X509_STRICT
Keeps chain, date and host name verification but skips RFC 5280 profile checks for this context; remove it after reissuing.
python # Temporary workaround until certificates are reissued import ssl ctx = ssl.create_default_context(cafile="ca.pem") ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT