Most people think pip just magically finds packages on the internet, but behind a corporate proxy, it’s actually a bit of a negotiation.
Let’s watch pip in action trying to fetch a package without proper configuration.
# Simulate fetching a package, but this will likely fail behind a proxy
pip install requests
You’ll probably see something like:
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 407 Proxy Authentication Required'))': /simple/requests/
This 407 Proxy Authentication Required is the key. It means pip tried to talk to a proxy server, and that server said, "Who are you?" and demanded credentials. The Tunnel connection failed part is pip attempting to establish a secure tunnel through the proxy to reach the package index (like PyPI).
Here’s how to fix it. The most common way is to set environment variables.
1. Environment Variables (Most Common)
-
Diagnosis: Check if
HTTP_PROXYandHTTPS_PROXYare set in your environment.echo $HTTP_PROXY echo $HTTPS_PROXYIf they are empty or incorrect,
pipwon’t know where to go. -
Fix: Set them with your proxy details. Replace
user:passwordandproxy.example.com:portwith your actual corporate proxy information.export HTTP_PROXY="http://user:password@proxy.example.com:8080" export HTTPS_PROXY="http://user:password@proxy.example.com:8080"Why it works: These environment variables are a standard convention that many command-line tools, including
pip(via the underlyingrequestslibrary), look for to determine how to route outgoing HTTP and HTTPS requests.
2. Pip Configuration File (Persistent)
-
Diagnosis: Even with environment variables, you might want a permanent solution. Check your
pip.conforpip.inifile. On Linux/macOS, it’s usually in~/.config/pip/pip.confor~/.pip/pip.conf. On Windows, it’s%APPDATA%\pip\pip.ini. -
Fix: Add the following to your pip configuration file.
[global] proxy = http://user:password@proxy.example.com:8080Why it works: This directly tells
pipits proxy settings, overriding or supplementing environment variables forpipoperations specifically.
3. Command-Line Arguments (Per-Command)
-
Diagnosis: You’ve tried environment variables and config files, but it’s still not working, or you need a quick, one-off fix.
-
Fix: Pass the proxy directly to the
pipcommand.pip install --proxy http://user:password@proxy.example.com:8080 requestsWhy it works: This is the most explicit method, telling
pipexactly which proxy to use for that specific command execution.
4. Handling No-Proxy Lists
-
Diagnosis: Sometimes, you need to access internal resources directly without going through the proxy. Your
pipcommand might be trying to use the proxy for local hostnames, causing failures. -
Fix: Configure a
no_proxysetting. This can be done via environment variables or the pip config file.- Environment Variable:
export NO_PROXY="localhost,127.0.0.1,internal.company.com" - Pip Config:
[global] no-proxy = localhost,127.0.0.1,internal.company.com
Why it works:
pip(and its underlying libraries) will check this list. If the target host matches an entry, it will bypass the configured proxy and attempt a direct connection. - Environment Variable:
5. Specific Authentication Schemes
-
Diagnosis: Your proxy might use NTLM or Kerberos authentication, which the basic
user:password@host:portformat doesn’t handle. You’ll see errors related to authentication failures that aren’t just a simple bad username/password. -
Fix: Install the
requests-ntlmlibrary and use its authentication format.pip install requests-ntlm # Then, in your pip config or environment variable: # Note: The format might vary slightly depending on the library # This is a conceptual representation, actual implementation might differ # For environment variables, you might need to ensure the requests library # is configured to use NTLM when needed, often implicitly through the proxy URL structure. # A common pattern, though not universally supported by all proxy libraries without extra config, # is to include the authentication type in the URL if the library supports it. # More commonly, you'd configure this within an application's network settings that then uses pip.Self-correction: Direct configuration for NTLM/Kerberos within
pip’s proxy URL is less common than relying on the underlyingrequestslibrary’s capabilities or external configuration managers. The primary mechanism for advanced auth is often handled by tools that invokepip, or by ensuring therequestslibrary can negotiate it. For directpipusage, if the proxy URL formathttp://user:password@host:portdoesn’t work, and your proxy requires NTLM, you might need a more sophisticated proxy client or a tool that explicitly supports NTLM authentication forpip.Corrected Fix for NTLM/Kerberos: For NTLM or Kerberos, the standard
http://user:password@host:portoften won’t work directly. You typically need to ensure your system’s network configuration or a dedicated proxy client handles this negotiation.pipitself, when using the standardproxysetting, relies on therequestslibrary. Ifrequestscan’t negotiate NTLM/Kerberos via the basic URL, you might need to: a) Installrequests-ntlm(pip install requests-ntlm) and configurepipto use it. However,pip’sproxysetting doesn’t directly support specifying an auth method like NTLM. The integration is more complex and often involves setting system-wide proxy settings thatrequestscan leverage. b) Use a tool likecntlm(for NTLM) or configure system-level Kerberos. Then, pointpip’s proxy setting to the localcntlmor Kerberos proxy listener. Example withcntlm(conceptual): Ifcntlmis running and listening onlocalhost:3128for NTLM authentication:export HTTP_PROXY="http://localhost:3128" export HTTPS_PROXY="http://localhost:3128"Why it works:
cntlm(or a similar tool) acts as an intermediary. It intercepts yourpip’s requests, performs the NTLM/Kerberos handshake with your corporate proxy on your behalf, and then forwards the request to the actual proxy.
6. SSL Certificate Verification Issues
-
Diagnosis: Your corporate proxy might be intercepting and re-signing SSL traffic (SSL inspection/man-in-the-middle).
pipwill complain about untrusted certificates. -
Fix: Tell
pipto trust your corporate CA certificate.# Ensure your corporate CA cert is saved as a .pem file, e.g., /etc/ssl/certs/corp-ca.pem pip config set global.certfile /etc/ssl/certs/corp-ca.pemOr, less securely, disable verification entirely (not recommended for production):
pip config set global.ssl-verify falseWhy it works:
certfilepointspipto the Certificate Authority (CA) certificate that signed your proxy’s re-signed certificate, allowing it to be trusted.ssl-verify falsetellspipto skip all certificate checks.
After applying these fixes, the next error you’ll likely encounter, assuming everything else is correct, is a Timeout error if the proxy is slow, or a specific package not being found if there’s a typo in the package name or it’s not available on PyPI.