GeezerVison is showing github.com — Python 3.13: `[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)` · Issue #138193 · python/cpython
Python 3.13: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032) #138193DescriptionBug report
Bug description:
import requests
requests.get('https://www.google.com')
urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/requests/adapters.py", line 644, in send
resp = conn.urlopen(
method=request.method,
...<9 lines>...
chunked=chunked,
)
File "/usr/local/lib/python3.13/site-packages/urllib3/connectionpool.py", line 841, in urlopen
retries = retries.increment(
method, url, error=new_e, _pool=self, _stacktrace=sys.exc_info()[2]
)
File "/usr/local/lib/python3.13/site-packages/urllib3/util/retry.py", line 519, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.google.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
requests.get('https://www.google.com')
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
File "/usr/local/lib/python3.13/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python3.13/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.13/site-packages/requests/adapters.py", line 675, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.google.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)')))
The Linux machine is behind a corporate HTTP proxy with self-signed certificates.
The required Root CA Certificate has been added to the trust store, e.g. uploaded to /usr/local/share/ca-certificates followed by executing update-ca-certificates.
Furthermore the following environment variables are set:
ftp_proxy="ftp://<ftp-proxy-adress>:<ftp-proxy-port>/"
FTP_PROXY="ftp://<ftp-proxy-adress>:<ftp-proxy-port>/"
http_proxy="http://<http-proxy-adress>:<http-proxy-port>/"
HTTP_PROXY="http://<http-proxy-adress>:<http-proxy-port>/"
https_proxy="http://<http-proxy-adress>:<http-proxy-port>/"
HTTPS_PROXY="http://<http-proxy-adress>:<http-proxy-port>/"
no_proxy="127.0.0.1,localhost[,REDACTED]"
NO_PROXY="127.0.0.1,localhost[,REDACTED]"
CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt"
REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt"
SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
ℹ️ This setup works fine for Python 3.12 (using pip, urllib3, requests, etc.) but not for Python 3.13 (using pip it works, though).
The Root CA Certificate contains the following lines:
Certificate:
Data:
....
X509v3 extensions:
...
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:1
X509v3 Subject Key Identifier:
4E:32:71:1C:07:BB:1D:A8:A4:8A:F8:17:4B:B6:15:47:65:54:24:7E
X509v3 Authority Key Identifier:
4E:32:71:1C:07:BB:1D:A8:A4:8A:F8:17:4B:B6:15:47:65:54:24:7E
...
Is this, i.e. an AKI that matches the SKI, leading to the error?
- If yes: Is this considered a malformation?
- If yes: By CPython only or in general?
CPython versions tested on:
3.13
Operating systems tested on:
Linux Activitybenz0li commented on Aug 27, 2025 P.S: Everything works fine with intranet pages that use a Root CA Certificate that contains the X509v3 Subject Key Identifier line but not the X509v3 Authority Key Identifier line. StanFromIreland commented on Aug 27, 2025 benz0li commented on Aug 27, 2025
requests is not part of the stdlib, I suggest you open the issue in their tracker.
Is there a way to test this with stdlib only? In case this is related to
– which I am quite sure of – and thus caused by ssl (part of the Python Standard Library). benz0li commented on Aug 27, 2025 ZeroIntensity commented on Aug 27, 2025 Please check if the C script I posted there reproduces with whatever site you're using. If anything, this is probably an issue with OpenSSL. benz0li commented on Aug 27, 2025 Using curl as a reference for the same request on the same machine:
curl -sv -o /dev/null https://www.google.com
* Uses proxy env variable no_proxy == '127.0.0.1,localhost[,REDACTED]'
* Uses proxy env variable https_proxy == 'http://<http-proxy-address>:<http-proxy-port>/'
* Host <http-proxy-address>:<http-proxy-port> was resolved.
* IPv6: (none)
* IPv4: [REDACTED]
* Trying [REDACTED]...
* CONNECT tunnel: HTTP/1.1 negotiated
* allocate connect buffer
* Establish HTTP proxy tunnel to www.google.com:443
> CONNECT www.google.com:443 HTTP/1.1
> Host: www.google.com:443
> User-Agent: curl/8.14.1
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
< Proxy-Agent: Fortinet-Proxy/1.0
<
* CONNECT phase completed
* CONNECT tunnel established, response 200
* ALPN: curl offers h2,http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [1569 bytes data]
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [122 bytes data]
* TLSv1.3 (IN), TLS change cipher, Change cipher spec (1):
{ [1 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [6 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [4164 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [79 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / id-ecPublicKey
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=www.google.com
* start date: Jul 7 08:35:54 2025 GMT
* expire date: Aug 28 00:09:02 2025 GMT
* subjectAltName: host "www.google.com" matched cert's "www.google.com"
* issuer: C=[REDACTED]; O=[REDACTED]; OU=[REDACTED]; CN=[REDACTED]
* SSL certificate verify ok.
* Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 1: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
* Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
* Connected to <http-proxy-address> ([REDACTED]) port <http-proxy-port>
* using HTTP/1.x
} [5 bytes data]
> GET / HTTP/1.1
> Host: www.google.com
> User-Agent: curl/8.14.1
> Accept: */*
>
* Request completely sent off
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [553 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [553 bytes data]
< HTTP/1.1 200 OK
< Date: Wed, 27 Aug 2025 16:34:31 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
< Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-ukDNDhDEOHNObT0k4kV5zQ' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
< Accept-CH: Sec-CH-Prefers-Color-Scheme
< P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
< Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
< Server: gws
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: AEC=[REDACTED]; expires=Mon, 23-Feb-2026 16:34:31 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
< Set-Cookie: __Secure-ENID=28.SE=[REDACTED]; expires=Sun, 27-Sep-2026 08:52:49 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
< Accept-Ranges: none
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<
{ [15162 bytes data]
* Connection #0 to host <http-proxy-address> left intact
benz0li commented on Aug 27, 2025
Please check if the C script I posted there reproduces with whatever site you're using. If anything, this is probably an issue with OpenSSL.
Happy to do so.
I copied to test.c and tried compiling (cc test.c):
/usr/bin/ld: /tmp/ccUUSGKN.o: in function `ssl_perror':
test.c:(.text+0xd): undefined reference to `ERR_get_error'
/usr/bin/ld: test.c:(.text+0x22): undefined reference to `ERR_error_string'
/usr/bin/ld: /tmp/ccUUSGKN.o: in function `main':
test.c:(.text+0x64): undefined reference to `OPENSSL_init_ssl'
/usr/bin/ld: test.c:(.text+0x69): undefined reference to `TLS_client_method'
/usr/bin/ld: test.c:(.text+0x71): undefined reference to `SSL_CTX_new'
/usr/bin/ld: test.c:(.text+0x97): undefined reference to `BIO_new_ssl_connect'
/usr/bin/ld: test.c:(.text+0xd1): undefined reference to `BIO_ctrl'
/usr/bin/ld: test.c:(.text+0xec): undefined reference to `BIO_ctrl'
/usr/bin/ld: test.c:(.text+0x12c): undefined reference to `BIO_write'
/usr/bin/ld: test.c:(.text+0x15a): undefined reference to `BIO_read'
/usr/bin/ld: test.c:(.text+0x1a5): undefined reference to `BIO_free_all'
/usr/bin/ld: test.c:(.text+0x1b1): undefined reference to `SSL_CTX_free'
collect2: error: ld returned 1 exit status
Anything I am missing? I am not familiar with C. ZeroIntensity commented on Aug 27, 2025 You need to link OpenSSL. Off the top of my head, it's -lssl in GCC. benz0li commented on Aug 27, 2025 Using cc test.c -lssl -lcrypto compilation succeeded. Executing ./a.out results in
BIO_do_connect: error:FFFFFFFF8000006E:system library::Connection timed out
Aborted (core dumped)
after some time.
@ZeroIntensity Please extend your C script so it respects proxy settings/'environment variables'.
Thank you. benz0li commented on Aug 27, 2025 And no, this is not an OpenSSL issue.
Tested using openssl itself for the same request on the same machine:
openssl s_client -proxy <http-proxy-url>:<http-proxy-port> -connect www.google.com:443
Connecting to [REDACTED]
CONNECTED(00000003)
depth=2 C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
verify return:1
depth=1 C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
verify return:1
depth=0 CN=www.google.com
verify return:1
---
Certificate chain
0 s:CN=www.google.com
i:C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
a:PKEY: EC, (prime256v1); sigalg: sha256WithRSAEncryption
v:NotBefore: Jul 7 08:35:54 2025 GMT; NotAfter: Aug 28 00:07:37 2025 GMT
1 s:C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
i:C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
a:PKEY: RSA, 2048 (bit); sigalg: sha256WithRSAEncryption
v:NotBefore: Sep 25 15:22:53 2024 GMT; NotAfter: Sep 25 15:22:53 2026 GMT
2 s:C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
i:C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
a:PKEY: RSA, 4096 (bit); sigalg: sha256WithRSAEncryption
v:NotBefore: Nov 4 13:38:36 2020 GMT; NotAfter: Nov 2 13:38:36 2030 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
[REDACTED]
-----END CERTIFICATE-----
subject=CN=www.google.com
issuer=C=[REDACTED], O=[REDACTED], OU=[REDACTED], CN=[REDACTED]
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ecdsa_secp256r1_sha256
Peer Temp Key: X25519, 253 bits
---
SSL handshake has read 4593 bytes and written 1705 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Protocol: TLSv1.3
Server public key is 256 bit
This TLS version forbids renegotiation.
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
closed
benz0li commented on Aug 27, 2025 I suspect the issue being caused by the following:
The Root CA Certificate contains the following lines:
Certificate:
Data:
....
X509v3 extensions:
...
X509v3 Basic Constraints: critical
CA:TRUE, pathlen:1
X509v3 Subject Key Identifier:
4E:32:71:1C:07:BB:1D:A8:A4:8A:F8:17:4B:B6:15:47:65:54:24:7E
X509v3 Authority Key Identifier:
4E:32:71:1C:07:BB:1D:A8:A4:8A:F8:17:4B:B6:15:47:65:54:24:7E
...
Is this, i.e. an AKI that matches the SKI, leading to the error?
benz0li commented on Aug 27, 2025
There is nothing wrong with the Root CA Certificate.
– PKI team
Is It wrong for a Root CA to have an AKI?
Not necessarily. While not required, it's not incorrect either. Here's the nuance:
- RFC 5280 (the standard for X.509 certificates) allows Root CAs to include an AKI that matches the SKI.1
- This can help systems that rely on AKI to build trust chains, especially in environments with multiple Root CAs.
However:
- Some SSL/TLS clients or libraries (especially custom or strict ones) may misinterpret this and expect the AKI to point to a different issuer.
- This can lead to validation failures like the one you're seeing.
– Copilot
benz0li commented on Aug 28, 2025 ZeroIntensity commented on Aug 29, 2025 Can you check if any of those commits in-between 3.12b1 and 3.13a0 reproduce it? benz0li commented on Aug 29, 2025 StanFromIreland commented on Aug 29, 2025 Please don't copy the same message again, it just makes the thread confusing, and unnecessarily long. ZeroIntensity commented on Aug 29, 2025 I'm lost at this point. There's not really any way that the version bump could be the regressing commit. I guess you could try reverting smaller parts of the version bump to see if any single change to a file causes the regression? StanFromIreland commented on Aug 29, 2025 Maybe there is some gated code (depending on the version) in requests causing the error? benz0li commented on Aug 29, 2025
Maybe there is some gated code (depending on the version) in requests causing the error?
Highly likely.
I tested with stdlib's http.client and everything seems fine:
Python 3.13.0a0 (heads/3.13:bc285c667c9, Aug 29 2025, 09:22:38) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import http.client
>>>
>>> conn = http.client.HTTPSConnection('<http-proxy-adress>', <http-proxy-port>)
>>> conn.set_tunnel('www.google.com')
>>> conn.request('GET', '/')
>>>
>>> resp = conn.getresponse()
>>> print(resp.status, resp.reason)
200 OK
>>>
>>> conn.close()
>>>
Seems to be an urllib3 issue. I will open an issue at https://github.com/urllib3/urllib3. ZeroIntensity commented on Aug 29, 2025 It would make more sense for it to be a urllib3 issue, but also quite confusing. Since it reproduces when 3.13 was equivalent to 3.12b1, there would have to be a 3.13 gate for a <3.12 feature. Not impossible, but certainly not common. benz0li commented on Aug 30, 2025
Since it reproduces when 3.13 was equivalent to 3.12b1, there would have to be a 3.13 gate for a <3.12 feature.
In urllib3, it triggers for sys.version_info >= (3, 13).
Cross reference:
benz0li commented on Aug 30, 2025 #138193 (comment) is wrong. I should have tested with a Python 3.13 release version.
I can reproduce with Python 3.13.7 stdlib's http.client:
Python 3.13.7 (main, Aug 15 2025, 02:33:33) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import http.client
>>> conn = http.client.HTTPSConnection('<http-proxy-adress>', <http-proxy-port>)
>>> conn.set_tunnel('www.google.com')
>>> conn.request('GET', '/')
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
conn.request('GET', '/')
~~~~~~~~~~~~^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1338, in request
self._send_request(method, url, body, headers, encode_chunked)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1384, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1333, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1093, in _send_output
self.send(msg)
~~~~~~~~~^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1037, in send
self.connect()
~~~~~~~~~~~~^^
File "/usr/local/lib/python3.13/http/client.py", line 1479, in connect
self.sock = self._context.wrap_socket(self.sock,
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
server_hostname=server_hostname)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/ssl.py", line 455, in wrap_socket
return self.sslsocket_class._create(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
sock=sock,
^^^^^^^^^^
...<5 lines>...
session=session
^^^^^^^^^^^^^^^
)
^
File "/usr/local/lib/python3.13/ssl.py", line 1076, in _create
self.do_handshake()
~~~~~~~~~~~~~~~~~^^
File "/usr/local/lib/python3.13/ssl.py", line 1372, in do_handshake
self._sslobj.do_handshake()
~~~~~~~~~~~~~~~~~~~~~~~~~^^
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)benz0li commented on Aug 30, 2025 #112389 is the culprit.
Branch 3.13, commit ea1803e 👉 No SSLError
Python 3.13.0a4+ (heads/3.13:ea1803e608a, Aug 30 2025, 06:18:41) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import http.client
>>>
>>> conn = http.client.HTTPSConnection('<http-proxy-adress>', <http-proxy-port>)
>>> conn.set_tunnel('www.google.com')
>>> conn.request('GET', '/')
>>>
>>> resp = conn.getresponse()
>>> print(resp.status, resp.reason)
200 OK
>>>
>>> conn.close()
Branch 3.13, commit 0876b92 👉 SSLError
Python 3.13.0a4+ (heads/3.13:0876b921b28, Aug 30 2025, 05:58:31) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import http.client
>>>
>>> conn = http.client.HTTPSConnection('<http-proxy-adress>', <http-proxy-port>)
>>> conn.set_tunnel('www.google.com')
>>> conn.request('GET', '/')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
conn.request('GET', '/')
~~~~~~~~~~~~^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1336, in request
self._send_request(method, url, body, headers, encode_chunked)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1382, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1331, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1091, in _send_output
self.send(msg)
~~~~~~~~~^^^^^
File "/usr/local/lib/python3.13/http/client.py", line 1035, in send
self.connect()
~~~~~~~~~~~~^^
File "/usr/local/lib/python3.13/http/client.py", line 1477, in connect
self.sock = self._context.wrap_socket(self.sock,
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^
server_hostname=server_hostname)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/ssl.py", line 455, in wrap_socket
return self.sslsocket_class._create(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
sock=sock,
^^^^^^^^^^
...<5 lines>...
session=session
^^^^^^^^^^^^^^^
)
^
File "/usr/local/lib/python3.13/ssl.py", line 1077, in _create
self.do_handshake()
~~~~~~~~~~~~~~~~~^^
File "/usr/local/lib/python3.13/ssl.py", line 1363, in do_handshake
self._sslobj.do_handshake()
~~~~~~~~~~~~~~~~~~~~~~~~~^^
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1033)
So it all boils down to #138193 (comment), i.e. whether an AKI that matches the SKI in a Root CA Certificate is supposed to be conisdered a malformation [by OpenSSL] or not. benz0li commented on Aug 30, 2025 nuclearpidgeon commented on Nov 24, 2025 For practicality purposes for anyone else (I see a few linked issues) hitting this error behind a corporate HTTP proxy with self-signed certificates that you're not able to just get quickly re-provisioned...
One workaround if you can control the SSL context being used is to just disable the VERIFY_X509_STRICT verification flag that is now set by default (courtesy @vstinner on #112389 (comment) ):
>>> import ssl
>>> ctx = ssl.create_default_context()
>>> ctx.verify_flags & ssl.VERIFY_X509_STRICT
<VerifyFlags.VERIFY_X509_STRICT: 32>
>>> ctx.verify_flags & ssl.VERIFY_X509_PARTIAL_CHAIN
<VerifyFlags.VERIFY_X509_PARTIAL_CHAIN: 524288>
>>> ctx.verify_flags &= ~(ssl.VERIFY_X509_STRICT | ssl.VERIFY_X509_PARTIAL_CHAIN)
>>> ctx.verify_flags & ssl.VERIFY_X509_STRICT
<VerifyFlags.VERIFY_DEFAULT: 0>
>>> ctx.verify_flags & ssl.VERIFY_X509_PARTIAL_CHAIN
<VerifyFlags.VERIFY_DEFAULT: 0>
This works as a solution for e.g. urllib3: urllib3/urllib3#3665 (comment)
As per the conversation above, /pull/112389 introduced the change causing the AKI validation behaviour by tightening the flags used in OpenSSL - it seems it got merged in to Python v3.13.0a5, so presumably it affects all 3.13 and later versions of Python. Reacted by PJ Farrell, garesbil9, Dustin Salmons, Zachary Weiss, niner, Daniel Dalavurak and Lukáš Sztefek Reacted by Bastien Humbert
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|