Skip to content

Fix: pip SSL: CERTIFICATE_VERIFY_FAILED certificate verify failed

FixDevs ·

Quick Answer

How to fix the pip SSL CERTIFICATE_VERIFY_FAILED error when installing Python packages, covering corporate proxies, trusted-host flags, certifi, pip.conf, macOS, Windows, and Docker environments.

The Error

You run pip install and get this:

pip install requests
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))
after connection broken by 'SSLError(SSLCertVerificationError(1,
'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer
certificate (_ssl.c:1129)'))': /simple/requests/

Or a variation like:

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:
self-signed certificate in certificate chain (_ssl.c:1129)')))

Every pip install fails. You cannot download any package from PyPI.

Why This Happens

When pip connects to pypi.org over HTTPS, Python’s ssl module verifies the server’s TLS certificate against a bundle of trusted Certificate Authority (CA) certificates. If that verification fails, pip refuses the connection.

There are several reasons the verification can fail:

Corporate proxy or firewall with SSL inspection. Your company’s network intercepts HTTPS traffic, strips the original certificate, and re-signs it with a corporate CA certificate. Python does not trust that corporate CA by default, so verification fails. This is the most common cause in workplace environments.

Outdated or missing CA certificates. The system’s CA certificate bundle or Python’s certifi package is outdated and does not include the CA that signed PyPI’s current certificate. This happens on older OS installations or isolated environments.

macOS Python installed from python.org. The official Python installer for macOS ships without system certificates. You need to run a post-install script to link Python to the system certificate store.

Custom Python builds or virtual environments with broken certificate paths. If Python was compiled from source or the virtual environment was created in a way that lost the certificate configuration, ssl cannot find any CA bundle at all.

Docker or CI environments with minimal base images. Stripped-down container images like alpine or slim variants may not include the ca-certificates package.

Antivirus software intercepting HTTPS. Some antivirus programs on Windows and macOS perform SSL inspection similar to corporate proxies, injecting their own root certificate into the chain.

Fix 1: Use the --trusted-host Flag

The fastest way to get past the error is to tell pip to skip certificate verification for PyPI:

pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org requests

You need all three hosts because pip fetches package metadata from pypi.org and downloads files from files.pythonhosted.org. The older pypi.python.org hostname is sometimes still used in redirects.

This works immediately but only applies to that single command. For a permanent configuration, see Fix 2.

Common Mistake: Using only --trusted-host pypi.org and forgetting files.pythonhosted.org. The install will still fail during the download phase because the actual package files are served from a different host.

Fix 2: Configure pip.conf or pip.ini Permanently

Instead of passing --trusted-host every time, set it in your pip configuration file.

On Linux and macOS, create or edit ~/.pip/pip.conf (or ~/.config/pip/pip.conf):

[global]
trusted-host = pypi.org
               pypi.python.org
               files.pythonhosted.org

On Windows, create or edit %APPDATA%\pip\pip.ini:

[global]
trusted-host = pypi.org
               pypi.python.org
               files.pythonhosted.org

Check where pip reads its configuration from:

pip config list -v

This shows all configuration files pip looks at and which ones exist. It helps you confirm your changes are being picked up.

For virtual environments, you can also place a pip.conf (or pip.ini on Windows) inside the virtual environment directory at venv/pip.conf.

Pro Tip: If you are in a corporate environment and need to point pip at a private PyPI mirror, combine trusted-host with index-url in the same config file:

[global]
index-url = https://nexus.internal.company.com/repository/pypi/simple/
trusted-host = nexus.internal.company.com

This way every pip install uses your internal mirror with the correct trust settings.

Fix 3: Add Your Corporate CA Certificate to certifi

If your organization uses SSL inspection, the right fix is to add the corporate root CA certificate to Python’s trusted certificate bundle instead of disabling verification.

First, find where certifi stores its CA bundle:

python -c "import certifi; print(certifi.where())"

This prints something like:

/home/user/.local/lib/python3.12/site-packages/certifi/cacert.pem

Get your corporate root CA certificate in PEM format. Your IT department can provide it, or you can export it from your browser. The file looks like:

-----BEGIN CERTIFICATE-----
MIIFkTCCA3mgAwIBAgIQB... (base64 encoded data)
-----END CERTIFICATE-----

Append it to the certifi bundle:

cat corporate-ca.pem >> $(python -c "import certifi; print(certifi.where())")

On Windows, use:

type corporate-ca.pem >> "$(python -c "import certifi; print(certifi.where())")"

After appending, pip will trust your corporate proxy’s certificates and verify them properly. No need for --trusted-host.

Note: This change is lost when you upgrade certifi (which happens when you upgrade pip or run pip install --upgrade certifi). You need to re-append the certificate after upgrades. Consider scripting this step.

Alternative: Use the SSL_CERT_FILE Environment Variable

Instead of modifying the certifi bundle, point Python at a custom certificate file:

export SSL_CERT_FILE=/path/to/corporate-ca-bundle.pem
pip install requests

The file must contain all CA certificates you need, including the standard ones. You can create a combined bundle:

cat $(python -c "import certifi; print(certifi.where())") corporate-ca.pem > combined-ca-bundle.pem
export SSL_CERT_FILE=$(pwd)/combined-ca-bundle.pem

Make this permanent by adding the export line to your ~/.bashrc or ~/.zshrc.

On Windows, set it as a system environment variable:

[System.Environment]::SetEnvironmentVariable("SSL_CERT_FILE", "C:\certs\combined-ca-bundle.pem", "User")

The SSL_CERT_DIR variable also works if you want to point to a directory of individual certificate files.

Fix 4: Update certifi and pip

If the error is caused by an outdated CA bundle, updating fixes it. The catch is that pip itself is broken, so you need a workaround.

Use --trusted-host to bootstrap the update:

pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org --upgrade pip certifi

Or download the packages manually. On another machine with working pip:

pip download pip certifi -d ./packages/

Transfer the ./packages/ directory to the broken machine and install offline:

pip install --no-index --find-links=./packages/ pip certifi

After updating, test without --trusted-host:

pip install --verbose requests 2>&1 | head -20

If the error is gone, outdated certificates were the issue.

Fix 5: Run Install Certificates.command on macOS

If you installed Python from python.org on macOS, Python does not use the macOS system certificate store by default. The installer includes a script to fix this.

Open Finder and navigate to /Applications/Python 3.x/ (replace 3.x with your version). Double-click Install Certificates.command.

Or run it from the terminal:

/Applications/Python\ 3.12/Install\ Certificates.command

This script does two things:

  1. Installs or upgrades the certifi package.
  2. Creates a symlink from Python’s expected certificate location to the certifi CA bundle.

After running it, pip should work without SSL errors.

If you installed Python via Homebrew on macOS, this step is not needed. Homebrew’s Python already uses the correct certificate paths. If you still get the error with Homebrew Python, the issue is likely a corporate proxy (see Fix 3) or you need to update your system certificates:

brew reinstall ca-certificates
brew reinstall openssl

Fix 6: Fix Certificates in Docker and CI Environments

Minimal Docker images often lack CA certificates. Install them based on your base image.

Debian/Ubuntu-based images:

RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates

Alpine-based images:

RUN apk add --no-cache ca-certificates

For corporate proxy certificates in Docker, copy your CA certificate into the build:

COPY corporate-ca.pem /usr/local/share/ca-certificates/corporate-ca.crt
RUN update-ca-certificates

Then set the environment variable so Python picks it up:

ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

In CI pipelines (GitHub Actions, GitLab CI, Jenkins), the same principles apply. If the CI runner is behind a corporate proxy, add the CA certificate to the runner image or set SSL_CERT_FILE in the pipeline environment variables.

For GitHub Actions specifically, the hosted runners already have up-to-date certificates. If you see this error there, it is almost always because your workflow is connecting to a self-hosted registry or internal server with a non-public certificate.

Fix 7: Update System CA Certificates

Your operating system maintains its own CA certificate store. If it is outdated, Python may inherit stale certificates.

Ubuntu/Debian:

sudo apt-get update && sudo apt-get install -y ca-certificates
sudo update-ca-certificates

CentOS/RHEL/Fedora:

sudo yum install ca-certificates
sudo update-ca-trust

Windows:

Windows updates its certificate store through Windows Update. Run Windows Update and restart. You can also manually manage certificates through the Certificate Manager:

certmgr.msc

Check if Python is using the system certificate store or its own certifi bundle:

python -c "import ssl; print(ssl.get_default_verify_paths())"

This shows the paths Python checks for certificates. If openssl_cafile and openssl_capath are empty or point to nonexistent paths, Python falls back to certifi.

On Windows with Python 3.4+, you can force Python to use the Windows certificate store by using the pip-system-certs package:

pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org pip-system-certs

This package monkey-patches ssl to load certificates from the Windows certificate store, which includes any corporate CA certificates your IT team has deployed via Group Policy.

Fix 8: Handle Antivirus SSL Interception

Some antivirus software on Windows and macOS intercepts HTTPS connections, similar to a corporate proxy. Common offenders include Kaspersky, ESET, Avast, and Bitdefender.

To test if antivirus is the cause, temporarily disable the “Web Protection” or “HTTPS Scanning” feature in your antivirus settings, then try pip install again. If it works, the antivirus is the problem.

Permanent fixes:

  1. Add an exception in your antivirus for pip.exe or python.exe so it does not inspect their HTTPS traffic.
  2. Export the antivirus root certificate and add it to certifi (same process as Fix 3).
  3. Disable HTTPS scanning in the antivirus settings if your security policy allows it.

Check which certificate is actually being served:

python -c "
import ssl, socket
ctx = ssl.create_default_context()
with ctx.wrap_socket(socket.socket(), server_hostname='pypi.org') as s:
    s.connect(('pypi.org', 443))
    cert = s.getpeercert()
    print(cert['issuer'])
"

If the issuer shows your antivirus vendor instead of a public CA like DigiCert or Let’s Encrypt, the antivirus is intercepting the connection.

You can disable SSL verification entirely:

[global]
trusted-host = pypi.org
               pypi.python.org
               files.pythonhosted.org
cert =

Or per-command:

pip install --cert "" requests

Or with an environment variable:

export PIP_CERT=""
pip install requests

Warning: Disabling SSL verification exposes you to man-in-the-middle attacks. A malicious actor on your network could serve tampered packages. Only use this as a last-resort debugging step, never in production or CI environments. Once you confirm that SSL verification is the issue, go back and implement a proper fix (Fix 3 or Fix 7).

Verifying Your Fix

After applying any of the fixes above, confirm that pip works correctly:

pip install --upgrade pip
pip install requests

Check that Python can verify the PyPI certificate:

python -c "
import urllib.request
response = urllib.request.urlopen('https://pypi.org')
print(f'Status: {response.status}')
print('SSL verification OK')
"

If you are using requests in your own code and hit CERTIFICATE_VERIFY_FAILED there too, the same underlying fixes apply. The requests library uses certifi for certificate verification, so adding your CA to the certifi bundle (Fix 3) resolves both pip and requests errors.

For issues with other SSL certificate errors in tools like Git, curl, or Node.js, see SSL certificate problem: unable to get local issuer certificate.

Still Not Working?

Check your Python version. Older Python versions (3.5 and below) use outdated TLS libraries that may not support modern certificate chains. Upgrade to Python 3.9+ if possible:

python --version

Check if a VPN is interfering. Some VPN clients install their own root certificates or route traffic through a proxy. Disconnect the VPN and try again. If pip works without the VPN, treat it like a corporate proxy issue (Fix 3).

Verify the system clock. SSL certificates have validity periods. If your system clock is wrong (common in VMs or containers), certificates appear expired:

date

If the date is wrong, fix it:

sudo timedatectl set-ntp on

Try a different Python installation. If you have multiple Python versions, try another one. A Homebrew-installed Python on macOS or a pyenv-managed version may have different certificate configurations than the system Python:

python3.12 -m pip install requests

Check if only specific packages fail. If pip works for some packages but not others, the issue might be with a private index or extra index URL in your pip configuration, not with PyPI itself:

pip config list

Look for index-url or extra-index-url entries pointing to internal servers.

Use --verbose for more detail. The verbose flag shows exactly which certificate file pip is using and where the verification fails:

pip install --verbose requests 2>&1 | grep -i ssl

If you are hitting pip errors unrelated to SSL, such as build failures or environment issues, check out these guides:

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles