GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

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) #138193

New issue
Copy link
New issue
Copy link
Closed as not planned
Closed as not planned
Python 3.13: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032)#138193
Copy link
Labels
3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesextension-modulesC modules in the Modules dirC modules in the Modules dirpendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is providedtopic-SSLtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@benz0li
benz0li
opened on Aug 27, 2025
Issue body actions

Bug 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

Activity

Next
  1. benz0li
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Aug 27, 2025
  2. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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.

  3. StanFromIreland commented on Aug 27, 2025

    @StanFromIreland
    StanFromIreland
    on Aug 27, 2025
    Member
    More actions

    requests is not part of the stdlib, I suggest you open the issue in their tracker.

  4. StanFromIreland
    added
    pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is provided
    on Aug 27, 2025
  5. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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

    • ssl.create_default_context(): add VERIFY_X509_STRICT and VERIFY_X509_PARTIAL_CHAIN to the default verify_flags #107361
      • gh-107361: strengthen default SSL context flags #112389

    – which I am quite sure of – and thus caused by ssl (part of the Python Standard Library).

  6. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    Similar issue:

    • SSL: CERTIFICATE_VERIFY_FAILED when using custom root CA in Windows #135408
  7. ZeroIntensity commented on Aug 27, 2025

    @ZeroIntensity
    ZeroIntensity
    on Aug 27, 2025
    Member
    More actions

    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.

  8. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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
    
  9. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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.

  10. ZeroIntensity commented on Aug 27, 2025

    @ZeroIntensity
    ZeroIntensity
    on Aug 27, 2025
    Member
    More actions

    You need to link OpenSSL. Off the top of my head, it's -lssl in GCC.

  11. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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.

  12. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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
    
  13. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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?

    • If yes: Is this considered a malformation?

      • If yes: By CPython only or in general?
  14. benz0li commented on Aug 27, 2025

    @benz0li
    benz0li
    on Aug 27, 2025
    Author
    More actions

    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

    Footnotes

    1. https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.1 ↩

  15. benz0li commented on Aug 28, 2025

    @benz0li
    benz0li
    on Aug 28, 2025
    Author
    More actions

    Any update on this?

  16. 22 remaining items

  17. ZeroIntensity commented on Aug 29, 2025

    @ZeroIntensity
    ZeroIntensity
    on Aug 29, 2025
    Member
    More actions

    Can you check if any of those commits in-between 3.12b1 and 3.13a0 reproduce it?

  18. benz0li commented on Aug 29, 2025

    @benz0li
    benz0li
    on Aug 29, 2025
    Author
    More actions

    Can you check if any of those commits in-between 3.12b1 and 3.13a0 reproduce it?

    The build fails for 42974c4, 357bed0, 2c4e29e and 500b0f4.

    As already mentioned, e295d86 works.

    Also: #138193 (comment)

  19. StanFromIreland commented on Aug 29, 2025

    @StanFromIreland
    StanFromIreland
    on Aug 29, 2025
    Member
    More actions

    Please don't copy the same message again, it just makes the thread confusing, and unnecessarily long.

    Reacted by Olivier Benz
  20. ZeroIntensity commented on Aug 29, 2025

    @ZeroIntensity
    ZeroIntensity
    on Aug 29, 2025
    Member
    More actions

    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?

  21. StanFromIreland commented on Aug 29, 2025

    @StanFromIreland
    StanFromIreland
    on Aug 29, 2025
    Member
    More actions

    Maybe there is some gated code (depending on the version) in requests causing the error?

  22. benz0li commented on Aug 29, 2025

    @benz0li
    benz0li
    on Aug 29, 2025
    Author
    More actions

    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
    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.

  23. StanFromIreland
    added
    pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is provided
    on Aug 29, 2025
  24. ZeroIntensity commented on Aug 29, 2025

    @ZeroIntensity
    ZeroIntensity
    on Aug 29, 2025
    Member
    More actions

    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.

  25. benz0li commented on Aug 30, 2025

    @benz0li
    benz0li
    on Aug 30, 2025
    Author
    More actions

    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:

    • Set VERIFY flags in create_urllib3_context  urllib3/urllib3#3577
  26. benz0li commented on Aug 30, 2025

    @benz0li
    benz0li
    on Aug 30, 2025
    Author
    More actions

    #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
    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)
  27. benz0li commented on Aug 30, 2025

    @benz0li
    benz0li
    on Aug 30, 2025
    Author
    More actions

    #112389 is the culprit.


    Branch 3.13, commit ea1803e 👉 No SSLError

    python
    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
    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.

  28. benz0li commented on Aug 30, 2025

    @benz0li
    benz0li
    on Aug 30, 2025
    Author
    More actions

    Closed in favour of

    • verify_flag VERIFY_X509_STRICT: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority Key Identifier (_ssl.c:1032) openssl/openssl#28391
  29. benz0li
    closed this as completedon Aug 30, 2025
  30. StanFromIreland
    closed this as not plannedon Aug 30, 2025
  31. nuclearpidgeon commented on Nov 24, 2025

    @nuclearpidgeon
    nuclearpidgeon
    on Nov 24, 2025
    More actions

    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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixes3.15bugs and security fixesbugs and security fixesextension-modulesC modules in the Modules dirC modules in the Modules dirpendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is providedtopic-SSLtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.