Search code examples
pythonpipwindows-subsystem-for-linuxpipenv

Pip/Pipenv Can't Download Any Packages with Read Timeout (Ubuntu 22.04 WSL 2)


This is driving me a little crazy. For some reason, immediately after upgrading to Windows 11 22H2, neither pip nor pipenv are able to successfully download packages at all. Error output is shown below from an attempt to update pip on a fresh install of WSL 2 Ubuntu 22.04 (and after initially installing pip older version via sudo apt install python3-pip). I should note, before this update, I had a working WSL 2 Ubuntu 22.04 environment with several projects and a dozen or so different packages successfully installed.

Context and things tried already:

  • Attempting to install different packages (pip itself, black, pandas, and others all have this issue)
  • From Pip Install hangs solution, I've tried installing via pip install package, python3 -m pip install package, and pipenv install package or python3 -m pipenv install package both inside and outside of pipenv virtual environment shell.
  • From the same solution I also tried export DISPLAY= and unset DISPLAY. I have no Xserver installed, and this is now a fresh install of Ubuntu 22.04 in WSL
  • Completely reinstalled Ubuntu 22.04 in WSL 2
  • Re-followed the steps of https://learn.microsoft.com/en-us/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package to ensure the kernel and WSL version are up to date
  • Disabled Windows firewall for private and public networks (temporarily)
  • Rebooted the PC (3 times)
  • Rebooted the router
  • Checked from another computer with WSL 2 Ubuntu 22.04 and successfully grabbed packages normally
  • Check ping pypi.org for a response and checked that PyPi servers have no reported outages
  • Completely disabled IPv6 in Windows for my Ethernet interface and restarted the interface a few times
  • Trying the suggested edits to /etc/gai.conf from ReadTimeoutError/pip not installling any library to prefer ipv4 connecton and rebooting

Symptoms are always the same, any ideas?

user@NAME:~/stem-cutpoint$ python3 -m pip install --upgrade pip
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: pip in /usr/lib/python3/dist-packages (22.0.2)
Collecting pip
  Downloading pip-23.0.1-py3-none-any.whl (2.1 MB)
     ╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0.0/2.1 MB 3.1 MB/s eta 0:00:01
ERROR: Exception:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/_vendor/urllib3/response.py", line 438, in _error_catcher
    yield
  File "/usr/lib/python3/dist-packages/pip/_vendor/urllib3/response.py", line 519, in read
    data = self._fp.read(amt) if not fp_closed else b""
  File "/usr/lib/python3/dist-packages/pip/_vendor/cachecontrol/filewrapper.py", line 90, in read
    data = self.__fp.read(amt)
  File "/usr/lib/python3.10/http/client.py", line 465, in read
    s = self.fp.read(amt)
  File "/usr/lib/python3.10/socket.py", line 705, in readinto
    return self._sock.recv_into(b)
  File "/usr/lib/python3.10/ssl.py", line 1274, in recv_into
    return self.read(nbytes, buffer)
  File "/usr/lib/python3.10/ssl.py", line 1130, in read
    return self._sslobj.read(len, buffer)
TimeoutError: The read operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/base_command.py", line 165, in exc_logging_wrapper
    status = run_func(*args)
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/req_command.py", line 205, in wrapper
    return func(self, options, args)
  File "/usr/lib/python3/dist-packages/pip/_internal/commands/install.py", line 339, in run
    requirement_set = resolver.resolve(
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/resolver.py", line 94, in resolve
    result = self._result = resolver.resolve(
  File "/usr/lib/python3/dist-packages/pip/_vendor/resolvelib/resolvers.py", line 481, in resolve
    state = resolution.resolve(requirements, max_rounds=max_rounds)
  File "/usr/lib/python3/dist-packages/pip/_vendor/resolvelib/resolvers.py", line 348, in resolve
    self._add_to_criteria(self.state.criteria, r, parent=None)
  File "/usr/lib/python3/dist-packages/pip/_vendor/resolvelib/resolvers.py", line 172, in _add_to_criteria
    if not criterion.candidates:
  File "/usr/lib/python3/dist-packages/pip/_vendor/resolvelib/structs.py", line 151, in __bool__
    return bool(self._sequence)
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 155, in __bool__
    return any(self)
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 143, in <genexpr>
    return (c for c in iterator if id(c) not in self._incompatible_ids)
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 97, in _iter_built_with_inserted
    candidate = func()
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/factory.py", line 215, in _make_candidate_from_link
    self._link_candidate_cache[link] = LinkCandidate(
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/candidates.py", line 288, in __init__
    super().__init__(
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/candidates.py", line 158, in __init__
    self.dist = self._prepare()
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/candidates.py", line 227, in _prepare
    dist = self._prepare_distribution()
  File "/usr/lib/python3/dist-packages/pip/_internal/resolution/resolvelib/candidates.py", line 299, in _prepare_distribution
    return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
  File "/usr/lib/python3/dist-packages/pip/_internal/operations/prepare.py", line 487, in prepare_linked_requirement
    return self._prepare_linked_requirement(req, parallel_builds)
  File "/usr/lib/python3/dist-packages/pip/_internal/operations/prepare.py", line 532, in _prepare_linked_requirement
    local_file = unpack_url(
  File "/usr/lib/python3/dist-packages/pip/_internal/operations/prepare.py", line 214, in unpack_url
    file = get_http_url(
  File "/usr/lib/python3/dist-packages/pip/_internal/operations/prepare.py", line 94, in get_http_url
    from_path, content_type = download(link, temp_dir.path)
  File "/usr/lib/python3/dist-packages/pip/_internal/network/download.py", line 146, in __call__
    for chunk in chunks:
  File "/usr/lib/python3/dist-packages/pip/_internal/cli/progress_bars.py", line 304, in _rich_progress_bar
    for chunk in iterable:
  File "/usr/lib/python3/dist-packages/pip/_internal/network/utils.py", line 63, in response_chunks
    for chunk in response.raw.stream(
  File "/usr/lib/python3/dist-packages/pip/_vendor/urllib3/response.py", line 576, in stream
    data = self.read(amt=amt, decode_content=decode_content)
  File "/usr/lib/python3/dist-packages/pip/_vendor/urllib3/response.py", line 512, in read
    with self._error_catcher():
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/usr/lib/python3/dist-packages/pip/_vendor/urllib3/response.py", line 443, in _error_catcher
    raise ReadTimeoutError(self._pool, None, "Read timed out.")
pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.

Solution

  • For anyone who runs into a similar issue. It appears to be an issue resulting from the upgrade of TLS version from 1.2 to 1.3 with 22H2 update. The issue is discussed here (https://learn.microsoft.com/en-us/answers/questions/1018468/unable-to-connect-to-network-after-windows-11-22h2), with instructions on how to force the TLS version change for WSL.

    However, I was able to get connections to work successfully just using a simple wsl --update from an elevated command prompt (based on a suggestion here https://github.com/microsoft/WSL/issues/4020). After WSL updated successfully, the issue dissapeared completely. Thanks to @ykhrustalev for your comments! It helped narrow down the issue to TLS handshaking specifically with pypi.org and pythonhosted.org.

    Unfortunately, I didn't save the full verbose output from unsuccessfully attempting curl -v https://files.pythonhosted.org while the issue was still present. But the symptom was that curl would hang seemingly forever at a certain TLS handshake stage (shown below). After updating WSL the successful connection curl output looks like this:

    *   Trying 151.101.1.63:443...
    * Connected to files.pythonhosted.org (151.101.1.63) port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    *  CAfile: /etc/ssl/certs/ca-certificates.crt
    *  CApath: /etc/ssl/certs
    * TLSv1.0 (OUT), TLS header, Certificate Status (22):
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS header, Certificate Status (22):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS header, Finished (20):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS header, Certificate Status (22):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS header, Finished (20):
    * TLSv1.2 (IN), TLS header, Certificate Status (22):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: CN=*.pythonhosted.org
    *  start date: Sep 27 20:45:08 2022 GMT
    *  expire date: Oct 29 20:45:07 2023 GMT
    *  subjectAltName: host "files.pythonhosted.org" matched cert's "*.pythonhosted.org"
    *  issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign Atlas R3 DV TLS CA 2022 Q3
    *  SSL certificate verify ok.
    * Using HTTP2, server supports multiplexing
    * Connection state changed (HTTP/2 confirmed)
    * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    * Using Stream ID: 1 (easy handle 0x55c87ff66550)
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    > GET / HTTP/2
    > Host: files.pythonhosted.org
    > user-agent: curl/7.81.0
    > accept: */*
    >
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    ------ PREVIOUSLY HUNG FOREVER HERE ------
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    < HTTP/2 200
    < content-type: text/html
    < server: nginx/1.13.9
    < accept-ranges: bytes
    < date: Tue, 28 Feb 2023 19:33:47 GMT
    < age: 6
    < x-served-by: cache-iad-kiad7000029-IAD, cache-bos4689-BOS
    < x-cache: HIT, HIT
    < x-cache-hits: 15, 1
    < x-timer: S1677612827.168999,VS0,VE3
    < vary: Accept-Encoding
    < strict-transport-security: max-age=31536000; includeSubDomains; preload
    < x-frame-options: deny
    < x-xss-protection: 1; mode=block
    < x-content-type-options: nosniff
    < x-permitted-cross-domain-policies: none
    < x-robots-header: noindex
    < content-length: 1853
    <
    <html>
      <head>
        <title>PyPI Package and Documentation Storage</title>
      </head>
      <body>
        <p>
          This site hosts packages and documentation uploaded by authors of
          packages on the
          <a href="http://pypi.python.org">Python Package Index</a>.
        </p>
        <h3>Legal Notice</h3>
        <p>
          The Python Software Foundation ("PSF") does not claim ownership of
          any third-party code or content ("third party content") placed on
          the web site and has no obligation of any kind with respect to such
          third party content. Any third party content provided in connection
          with this web site is provided on a non-confidential basis. The
          PSF is free to use or disseminate such content on an unrestricted
          basis for any purpose, and third party content providers grant the
          PSF and all other users of the web site an irrevocable, worldwide,
          royalty-free, nonexclusive license to reproduce, distribute, transmit,
          display, perform, and publish such content, incl* TLSv1.2 (IN), TLS header, Supplemental data (23):
    uding in digital form.
        </p>
        <p>
          Third party content providers represent and warrant that they have
          obtained the proper governmental authorizations for the export and
          reexport of any software or other content contributed to this web
          site by the third-party content provider, and further affirm that
          any United States-sourced cryptographic software is not intended for
          use by a foreign government end-user.
          Individuals and organizations are advised that the PyPI website
          is hosted in the US, with content delivery network points of presence
          as well as unofficial mirrors in several countries outside the US. Any
          uploads of packages must comply with United States export controls under
          the Export Administration Regulations.
        </p>
      </body>
    </html>
    * Connection #0 to host files.pythonhosted.org left intact