To use pip through a proxy, start with one temporary command: python -m pip install --proxy http://HOST:PORT PACKAGE. If that succeeds, move the same route to an environment variable or the appropriate pip configuration file only when the setting genuinely needs to persist. Inspect the active configuration before and after the change so a global, user, virtual-environment, or shell setting does not silently override another one.
Scope: this tutorial covers pip’s outbound HTTP proxy configuration on Windows, macOS, and Linux. It does not configure a private Python package index, intercept TLS, or change the proxy for every application. For the broader route and authentication model, use the Proxy Setup and Developer Guides hub, compare runtime clients in the cURL, Python Requests, and Node.js guide, and review proxy authentication.
Before changing pip, record the actual boundary
Write down the proxy scheme, gateway host, port, authentication method, and the package source pip must reach. The scheme before HOST describes how pip connects to the proxy. It does not describe the destination package URL. An HTTP proxy can carry an HTTPS request by creating a CONNECT tunnel, so an HTTPS destination does not automatically mean the proxy URL begins with https://.
Use placeholders in documentation and tickets. Keep the assigned secret in a protected environment or credential store and do not paste a working URL into chat, issue trackers, requirements files, shell history, or screenshots. If source-IP authentication is enabled, confirm the public egress address of the machine running pip; a private LAN address is not the address the proxy provider sees.
--proxy: test one pip command first
The current pip user guide documents the --proxy option in the form scheme://[user:passwd@]proxy.server:port. Calling pip through the Python interpreter also makes it clear which environment owns the command.
# macOS or Linux
python3 -m pip install --proxy http://HOST:PORT PACKAGE
# Windows PowerShell or Command Prompt
py -m pip install --proxy http://HOST:PORT PACKAGE
Choose a small, known package that is approved for the environment, or use the real locked requirement in a disposable virtual environment. Do not add --trusted-host to make a certificate error disappear. That option changes trust behavior for a package host and is not a proxy-authentication fix.
Expected observation: pip resolves the configured package index, connects to the proxy, establishes TLS to the package service, downloads package metadata, and either installs the selected package or reports a normal dependency result. A 407 means the proxy answered but rejected or did not receive acceptable proxy credentials. A certificate error occurs later in a different trust boundary and must be investigated separately.
Authenticated proxy URLs and special characters
If the proxy requires username/password authentication and the current policy permits URL user information, the temporary syntax is http://USER:PASSWORD@HOST:PORT. Characters such as @, :, /, #, and percent signs inside either credential must be percent-encoded. The official pip authentication documentation explains percent-encoding for credentials used in URLs. Although that page focuses on package repositories, the URL parsing rule is the same reason a raw special character can break a proxy URL before authentication is attempted.
Avoid printing the full command in CI logs. Prefer a secret-injection mechanism that masks values, and rotate a password if it appears in a build log or shell transcript. Proxy credentials and package-index credentials are independent. A 407 is a proxy challenge; a 401 from a private package repository belongs to the destination repository.
Environment variables: persist for one shell or process tree
pip recognizes the standard http_proxy, https_proxy, and no_proxy environment variables described in its user guide. Uppercase forms are also common, but mixing cases can create different behavior across tools and operating systems. Set both HTTP and HTTPS routes explicitly when the environment needs both, then launch pip from the same shell.
# macOS or Linux: current shell
export http_proxy='http://HOST:PORT'
export https_proxy='http://HOST:PORT'
export no_proxy='localhost,127.0.0.1,.internal.example'
python3 -m pip install PACKAGE
# Windows PowerShell: current process
$Env:http_proxy = 'http://HOST:PORT'
$Env:https_proxy = 'http://HOST:PORT'
$Env:no_proxy = 'localhost,127.0.0.1,.internal.example'
py -m pip install PACKAGE
The environment belongs to the shell and its child processes unless it is saved through an operating-system or CI setting. This makes it useful for a controlled build job: the values disappear with the job, and the project files remain unchanged. It can also affect other tools launched by the same shell, so keep the scope narrow and document why the variables are present.
no_proxy is a bypass list, not a list of proxy gateways. Add only destinations that must be reached directly, such as a loopback service or an approved internal package mirror. A broad suffix can unintentionally route many hosts outside the proxy. Test one bypassed host and one proxied host rather than assuming every client interprets the list identically.
Configuration files: choose global, user, or virtual-environment scope
The official pip configuration guide defines global, user, and site levels. “Site” means the active virtual environment, not a website. On current Windows systems, the global file is typically C:\ProgramData\pip\pip.ini, the user file is under %APPDATA%\pip\pip.ini, and a virtual environment can contain %VIRTUAL_ENV%\pip.ini. On Unix-like systems, pip reads documented global locations, a user file such as $HOME/.config/pip/pip.conf, and $VIRTUAL_ENV/pip.conf for the environment.
Use pip’s configuration command instead of guessing a path:
# Inspect files and values visible to this interpreter
python -m pip config debug
python -m pip config list -v
# Save only for the active virtual environment
python -m pip config --site set global.proxy http://HOST:PORT
# Save for the current user when policy requires it
python -m pip config --user set global.proxy http://HOST:PORT
The resulting INI entry is conceptually:
[global]
proxy = http://HOST:PORT
Do not create a user-level setting merely because one project needs it. A virtual-environment file is easier to reason about for an isolated development environment, but it can still expose a password if the environment directory is copied or archived. For CI, ephemeral environment variables or the platform’s secret-aware configuration are usually easier to revoke and audit.
Precedence: find the value that actually wins
pip combines configuration files from broader to narrower scope, then applies environment variables and command-line options. The configuration documentation states that command-line options override environment variables, which override configuration files; command-specific sections can override a global section within a file. PIP_CONFIG_FILE can point to another file loaded late in the sequence.
This ordering explains a common failure: a correct user file appears to have no effect because the active virtual environment contains another value, or a CI environment variable overrides both. Run python -m pip config debug with the same interpreter and shell that will install packages. Record filenames and non-secret host labels, but redact user information before sharing output.
For one diagnostic run, provide --proxy http://HOST:PORT. If the command behaves differently, the persistent configuration is the likely difference. Do not keep stacking settings at every level; remove the stale value and keep one accountable source.
Verify routing without weakening package security
- Create or activate a disposable virtual environment.
- Run
python -m pip --versionand record the interpreter path. - Run
python -m pip config debugand identify every loaded file. - Test one package operation with an explicit
--proxy. - Repeat using the chosen persistent scope, with the explicit option removed.
- Compare status, timing, and the exact failure layer.
- Delete the disposable environment or uninstall the test package if it is not needed.
pip is not an exit-IP checker, so do not infer the public address from a successful installation. If you need to prove the assigned route itself first, run the neutral layered method in How to Test If Your Proxy Is Working from the same host, then return to pip. Keep package hashes, TLS validation, and the configured index intact.
Removal: return pip and the shell to a known state
Remove a value from the same scope where it was set:
# Remove a virtual-environment value
python -m pip config --site unset global.proxy
# Remove a user value
python -m pip config --user unset global.proxy
# macOS or Linux: current shell
unset http_proxy https_proxy no_proxy
# Windows PowerShell: current process
Remove-Item Env:http_proxy, Env:https_proxy, Env:no_proxy -ErrorAction SilentlyContinue
Then run python -m pip config debug again. A manual edit can leave a duplicate entry in another file, and a persistent operating-system variable can repopulate a new shell. Verification after removal is part of the change, not housekeeping.
pip proxy troubleshooting by failure signal
| Signal | Boundary | First useful check |
|---|---|---|
| Connection refused or gateway name failure | Proxy host, port, DNS, route, or listener | Confirm the assigned endpoint and test its port once |
| 407 Proxy Authentication Required | Proxy authentication | Check method, encoded credentials, account state, or source-IP allowlist |
| 401 from a private index | Package repository authentication | Check repository credentials separately from proxy credentials |
| Certificate verify failed | TLS trust, clock, inspection policy, or hostname | Inspect the certificate chain; do not disable verification |
| Read timeout | Proxy tunnel, destination, or very small timeout | Compare a direct baseline and one conservative proxied retry |
| Setting appears ignored | Configuration precedence or wrong interpreter | Run pip config debug through the same Python executable |
| Internal mirror unexpectedly proxied | no_proxy scope |
Inspect the exact host and bypass suffix |
Follow the common proxy error guide when the failure is below pip. Do not cycle IPs after a package repository returns a policy or rate response. Preserve the status, hostname, time, pip version, and non-secret configuration source so the failure can be reproduced.
Security and operational limits: use approved repositories and packages, follow organization egress policy, keep secrets out of project files and logs, preserve TLS verification, and review a proxy or certificate change with the responsible network team. A proxy changes the outbound route; it does not make an untrusted package safe.
Choose a stable endpoint only after the pip test is repeatable
If builds require a stable, exclusive egress for an approved package workflow, record the required location, authentication method, concurrent jobs, expected download volume, and bypass list. Compare those requirements with current private proxy options only after one controlled pip installation works and the cleanup procedure has also been tested.

