Command-line tools
pip CERTIFICATE_VERIFY_FAILED: fix it without --trusted-host
Could not fetch URL https://pypi.org/simple/requests/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/requests/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate')))There was a problem confirming the ssl certificate ... CERTIFICATE_VERIFY_FAILED means pip connected to PyPI or your package index but could not verify its certificate. On company networks the cause is almost always a TLS-inspecting proxy whose root pip does not trust; elsewhere it is an old pip, a private index with an internal CA, or a misconfigured mirror.
Quick fix
Check your pip version first, because pip 24.2 and later also trust the operating system store:
python -m pip --version
python -m pip install --upgrade pip --cert /path/to/ca-bundle.pem
If you have a CA bundle that includes the proxy or internal root, make it permanent:
pip config set global.cert /path/to/ca-bundle.pem
# or per shell / CI job
export PIP_CERT=/path/to/ca-bundle.pem
Build ca-bundle.pem from the system bundle (for example /etc/ssl/certs/ca-certificates.crt) plus your root in PEM format, because --cert replaces the default list.
Causes
1. A corporate TLS-inspecting proxy
Most pip certificate errors on work machines come from a proxy or security gateway that re-signs HTTPS with a company root.
- Confirm:
openssl s_client -connect pypi.org:443 -servername pypi.org </dev/null | grep issuernames your company or a security vendor, not a public CA. - Fix: upgrade to pip 24.2+ on a machine where IT installed the root in the OS store, or pass the root with
--cert/PIP_CERT.
2. A private index with an internal CA
Nexus, Artifactory, devpi and similar servers are often issued certificates from an internal CA.
- Confirm: the error mentions your internal hostname, not pypi.org.
- Fix: add the internal root to the bundle you pass with
--cert, or install it in the OS store and use a pip version that reads it.
3. An old pip or Python
Old pip releases ship an old certifi bundle that lacks newer roots.
- Confirm:
pip --versionis years old, and the failing site chains to a recent root. - Fix: upgrade pip (with
--certif needed). On end-of-life Python versions, upgrade Python itself.
4. A mirror or index with a broken chain
A mirror that does not send its intermediate certificate fails in pip but may work in a browser.
- Confirm: test the mirror host in the SSL checker.
- Fix: switch to a correctly configured mirror or report it to the operator.
5. Proxy URL problems
If the message is WRONG_VERSION_NUMBER or EOF occurred in violation of protocol rather than a certificate error, the proxy setting is the problem; see WRONG_VERSION_NUMBER.
Fixes by environment
pip 24.2 and later trust the operating system store, so installing the root there fixes most cases; older pip needs --cert or PIP_CERT.
Windows: with pip 24.2+, roots deployed by Group Policy are trusted automatically. Older pip versions need --cert. The user config file is %APPDATA%\pip\pip.ini.
macOS: pip 24.2+ reads the keychain through truststore. A corporate root must be in the System keychain and trusted.
Linux: install the root with update-ca-certificates (Debian/Ubuntu) or update-ca-trust (RHEL family), then either rely on pip 24.2+ or set PIP_CERT to the system bundle.
Docker / CI:
COPY company-root.crt /usr/local/share/ca-certificates/
RUN update-ca-certificates
ENV PIP_CERT=/etc/ssl/certs/ca-certificates.crt
RUN python -m pip install -r requirements.txt
Other installers: conda uses its own ssl_verify setting (see CondaSSLError), which accepts a path to a CA bundle. uv can use the OS store with --native-tls or a bundle via SSL_CERT_FILE.
Don't do this
--trusted-host pypi.org --trusted-host files.pythonhosted.org. This is the most copied answer and it turns off certificate checks for those hosts. Packages are code you will run.- Switching the index URL to
http://together with--trusted-host. Every download is then readable and replaceable on the network path. --use-deprecated=legacy-certsto "go back to how it was". It removes OS store support and usually makes proxy problems worse.- Editing certifi's
cacert.peminside site-packages. The nextpip install --upgrade certifisilently reverts it; keep your own bundle file instead.
FAQ
Why does pypi.org open in the browser but pip fails?
The browser trusts roots from the operating system store, including a corporate proxy root pushed by IT. pip before 24.2 only trusted its bundled certifi list, which contains public roots only. Upgrade pip or pass the corporate bundle with --cert.
I cannot upgrade pip because pip itself fails. What now?
Pass the bundle once for the upgrade: python -m pip install --upgrade pip --cert /path/to/ca-bundle.pem. After that, pip 24.2+ also reads the OS store. If you have no bundle file, export the proxy root from the OS store as PEM and append it to a copy of certifi's file.
Is `--trusted-host pypi.org` a safe workaround?
No. The pip documentation describes it as marking a host as trusted even though it does not have valid or any HTTPS. pip will then install whatever that host, or anyone intercepting it, sends. Use it only for an internal plain-HTTP index on a trusted network, never for PyPI or public mirrors.
Where do I set the certificate permanently?
Run pip config set global.cert /path/to/ca-bundle.pem. It writes to your user config file (pip.conf on Linux and macOS, pip.ini on Windows). pip config debug shows every file pip reads and which values come from where.