pip's proxy failures all look alike from a distance: a wall of WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by ... lines, five of them, and then an ERROR: Could not find a version that satisfies the requirement that sends people looking for a package name problem that does not exist. The real error is inside the parentheses of the first warning, and it is one of a small set: ProxyError('Cannot connect to proxy.', ...), Tunnel connection failed: 407 Proxy Authentication Required, SSLError(SSLCertVerificationError(...)), or a ReadTimeoutError. Each is a different problem with a different fix, and this guide takes them one at a time after covering where pip gets its proxy from in the first place.
How pip finds a proxy
pip makes its network requests through a bundled copy of the requests library, and it inherits that library's habits.
- The
--proxyflag.pip install --proxy http://user:password@proxy.example.com:3128 packageapplies to one command. The argument is a full URL, credentials included. - The configuration file.
pip config set global.proxy http://proxy.example.com:3128writesproxy = ...under[global]in your user configuration. The file is~/.config/pip/pip.confon Linux (older layouts use~/.pip/pip.conf),~/Library/Application Support/pip/pip.confon macOS, and%APPDATA%\pip\pip.inion Windows.pip config debuglists every location pip consults and what each contains. - The
PIP_PROXYvariable. Every pip option can be set asPIP_<OPTION>in the environment, andPIP_PROXYis the proxy. - The standard variables.
HTTP_PROXY,HTTPS_PROXY, andNO_PROXY(upper or lower case) are honoured byrequests, so pip uses them whether or not it is configured itself. This is where forgotten proxies live.
Precedence runs flag, then environment, then configuration file. To see what pip is actually using, pip config list shows configured values and env | grep -i proxy shows the environment; between them they account for every proxy pip can see.
Setting and removing it
pip config set global.proxy http://alice:p%40ss@proxy.example.com:3128
pip config list
pip config unset global.proxy
The @ in the password p@ss is written %40, or pip reads everything after the first @ as the hostname. To bypass the proxy for an internal index, set NO_PROXY=pypi.internal.example.com,localhost in the environment; pip has no config key for exclusions of its own.
For sudo pip install, remember that sudo drops the environment by default, so a proxy in your shell variables vanishes; use sudo -E pip install ... to keep it, or put the proxy in /etc/pip.conf where root's pip will read it.
The errors
| Inside the retry warning | What it means | Fix |
|---|---|---|
ProxyError('Cannot connect to proxy.', NewConnectionError(... Connection refused)) | Nothing listens at the proxy address | Wrong address, port, or network |
ProxyError('Cannot connect to proxy.', NewConnectionError(... Name or service not known)) | The proxy hostname does not resolve here | Off-network leftover; unset it |
ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 407 Proxy Authentication Required')) | Login required at the proxy | Put encoded credentials in the URL |
Tunnel connection failed: 403 Forbidden | The proxy refuses tunnels to PyPI | Policy; ask for PyPI to be allowed, or use an internal mirror |
SSLError(SSLCertVerificationError(... unable to get local issuer certificate)) | An inspecting proxy re-signs HTTPS | --cert or global.cert with the corporate root |
ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org' ...) | The proxy is slow or stalling | --timeout, --retries, or a better proxy |
Missing dependencies for SOCKS support | A socks:// proxy without PySocks installed | Install PySocks first |
Cannot connect to proxy
pip never reached PyPI because it could not reach the proxy in front of it. The nested error says why. Connection refused is an address and port where nothing is listening: the port is wrong, the proxy is down, or you are on a network where it is not reachable. Name or service not known (or nodename nor servname provided on macOS, or getaddrinfo failed on Windows) is a hostname that does not resolve on this network, which is the signature of a corporate proxy still configured on a laptop at home. Find the setting with pip config list and env | grep -i proxy, and either unset it or make it conditional on the network. Test the proxy itself with curl, which shares the diagnosis: curl -v -x http://proxy.example.com:3128 https://pypi.org/simple/ -o /dev/null, covered in our curl proxy errors guide.
407 in the tunnel
PyPI is HTTPS, so pip asks the proxy for a tunnel, and the proxy answers 407: authenticate first. pip does not prompt; the credentials have to be part of the proxy URL, encoded. Where the proxy insists on NTLM or Kerberos, which pip cannot speak, the workaround is a local helper that signs in to the corporate proxy for you and listens on 127.0.0.1 as a plain proxy that pip can use. See 407 Proxy Authentication Required for the encoding and whitelist cases.
403 in the tunnel
The proxy authenticated you and then refused the tunnel to PyPI. That is policy, not misconfiguration: the organisation does not allow direct package installs from the internet. The answers are administrative, which is to say asking for pypi.org and files.pythonhosted.org to be allowed, or using the internal mirror the organisation provides through pip config set global.index-url.
The certificate error
CERTIFICATE_VERIFY_FAILED with unable to get local issuer certificate, often followed by Could not fetch URL https://pypi.org/simple/...: There was a problem confirming the ssl certificate, means an inspecting proxy sits in the middle of the HTTPS connection and answers with a certificate issued by the organisation's own authority rather than PyPI's. Python's bundle does not include that authority. The fixes, from most to least specific:
pip install --cert /path/to/corporate-root.pem package
pip config set global.cert /path/to/corporate-root.pem
export REQUESTS_CA_BUNDLE=/path/to/corporate-root.pem
The first is one command, the second is permanent for pip, and the third covers every tool built on requests, which includes a great deal of Python. The file is the authority's root certificate in PEM form, from IT or exported from the system store.
The workaround that circulates everywhere is --trusted-host pypi.org --trusted-host files.pythonhosted.org. It works by telling pip not to verify those hosts at all, which means any machine in the middle can hand you any package. Use it once to confirm the diagnosis, then install the certificate.
Timeouts
A ReadTimeoutError against files.pythonhosted.org through a proxy is a proxy that is slow or stalling on large downloads. pip install --timeout 120 --retries 10 gives it room, and a proxy that answers the checker in seconds rather than milliseconds is one to replace rather than wait for.
SOCKS
pip can use a SOCKS proxy through requests, with the PySocks package installed and a socks5h:// URL so that the proxy performs the lookups. The catch is ordering: pip cannot install PySocks through a SOCKS proxy it does not yet understand, so install it first with the proxy variables unset or from a downloaded wheel, then configure the proxy. Missing dependencies for SOCKS support is the message when the order is wrong.
The misleading final line
After the retries, pip prints ERROR: Could not find a version that satisfies the requirement package (from versions: none) and ERROR: No matching distribution found for package. The package exists. pip is saying it found no versions because it never received the index. from versions: none is the tell; the real error is in the first warning above it.
Other Python tools
uv, poetry, pipx, and conda each make their own connections. uv and poetry honour the HTTP_PROXY, HTTPS_PROXY, and NO_PROXY variables and use their own certificate settings; conda has proxy_servers in .condarc. The environment variables are the one setting that covers all of them, which is the strongest argument for putting the proxy there rather than in pip's own file.
The proxy for pip is not the proxy for your code
Configuring pip's proxy does nothing for the Python you write with the packages it installs. A script using requests or httpx opens its own connections and needs its own proxies argument or environment, and its errors are the same family with different framing. Proxies with Python requests covers that side, including requests.exceptions.ProxyError in scripts and the session settings that keep a scraper on one exit.
What to remember
Read the first retry warning, not the last error. pip config list and env | grep -i proxy find every proxy in play. Set with --proxy or global.proxy, credentials encoded. Point pip at the corporate authority with --cert rather than reaching for --trusted-host. Install PySocks before a SOCKS proxy. And from versions: none means the index never arrived, not that the package is missing.