Skip to main content

How to Resolve Python Pip Error "connection error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed"

When interacting with HTTPS servers using Python tools like pip or libraries such as requests, you might encounter an error similar to connection error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed. This error indicates that your Python environment was unable to verify the authenticity of the SSL/TLS certificate presented by the remote server (like PyPI for pip or an API endpoint for requests). This verification failure often stems from issues with Certificate Authority (CA) bundles, network proxies, or system configurations.

This guide explains the common causes of this critical security error and provides solutions to resolve it correctly and securely.

Understanding the Error: SSL/TLS Certificate Verification

Secure websites and servers use SSL/TLS certificates to prove their identity to clients (like your Python script or pip). This process works like a digital passport:

  1. The server presents its certificate.
  2. The certificate is signed by a trusted third party called a Certificate Authority (CA).
  3. Your system/Python environment checks if it trusts the CA that signed the certificate by looking it up in a list (bundle) of known, trusted root CAs.
  4. It also checks if the certificate is valid (not expired, matches the hostname, etc.).

The CERTIFICATE_VERIFY_FAILED error means step 3 or 4 failed. Your system could not validate the chain of trust back to a recognized root CA in its store, or found another issue with the certificate's validity. This is a critical security check to prevent Man-in-the-Middle (MitM) attacks.

Common Causes

  • Outdated/Missing CA Certificates: Your system's or Python environment's list of trusted root CAs might be outdated or incomplete. Python packages like requests and pip often rely on the certifi package for a current CA bundle.
  • Network Interception (Proxies, Firewalls, Antivirus): In corporate environments, network proxies or "transparent" firewalls often intercept HTTPS traffic. They decrypt it, inspect it, and then re-encrypt it using their own certificate, which is typically signed by an internal corporate CA. Your system needs to be configured to trust this internal CA, otherwise verification will fail. Some overly aggressive antivirus software can also interfere similarly.
  • Incorrect System Time: SSL certificates have validity periods (start and end dates). If your computer's clock is significantly incorrect, it might perceive a valid certificate as expired or not yet valid.
  • Server-Side Certificate Issues: Less commonly, the server itself might be misconfigured, presenting an expired, revoked, self-signed, or otherwise invalid certificate.

Solution 1: Update CA Certificates (certifi and System)

Ensuring your CA bundle is up-to-date is often the first and best step.

  • Update certifi: Many Python tools rely on this package.
    pip install --upgrade certifi
    # Or: python -m pip install --upgrade certifi
  • Update System CA Certificates: Your operating system also maintains a list of trusted CAs. Ensure your OS is up-to-date. Specific commands vary:
    • Debian/Ubuntu: sudo apt-get update && sudo apt-get install --reinstall ca-certificates && sudo update-ca-certificates
    • RHEL/CentOS/Fedora: sudo yum update ca-certificates or sudo dnf update ca-certificates
    • macOS: Usually updated via System Updates. You can check/manage certs in Keychain Access.
    • Windows: Usually updated via Windows Update. You can check/manage certs using certmgr.msc.

After updating, retry the operation (pip install or your script).

Solution 2: Configure Pip trusted-host (Use with Caution)

If the error occurs specifically with pip connecting to PyPI or an internal index, and you understand the security implications (you trust the connection path or it uses other security), you can tell pip to trust specific hosts without verifying their SSL certificates. This lowers security for that host.

  • Command Line (Temporary):
    # Trust pypi.org and files.pythonhosted.org for this command only
    pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org package_name
  • Configuration File (Persistent): Add the hosts to your pip.conf (Linux/macOS: ~/.config/pip/pip.conf or ~/.pip/pip.conf) or pip.ini (Windows: %APPDATA%\pip\pip.ini or %HOME%\pip\pip.ini).
    [global]
    trusted-host =
    pypi.org
    files.pythonhosted.org
    your.internal.pypi.mirror
  • Using pip config command:
    # Append a trusted host (might need multiple commands for multiple hosts)
    pip config set global.trusted-host "pypi.org files.pythonhosted.org" # Check format, might vary
note

Use trusted-host sparingly and only for hosts you genuinely trust or for which certificate verification is known to fail due to internal network configurations.

Solution 3: Configure Pip/Requests with a Custom CA Bundle (--cert, REQUESTS_CA_BUNDLE)

This is the standard solution when dealing with corporate proxies/firewalls that use an internal CA certificate. Your network administrator should provide you with the public certificate file (.pem, .crt) for the internal CA.

  • For pip: Use the --cert option.
    pip install --cert /path/to/your/corporate_ca_bundle.pem package_name
    You can add this permanently to pip.conf/pip.ini:
    [global]
    cert = /path/to/your/corporate_ca_bundle.pem
  • For requests (and libraries using it):
    • Set the REQUESTS_CA_BUNDLE environment variable:
      # Linux/macOS
      export REQUESTS_CA_BUNDLE=/path/to/your/corporate_ca_bundle.pem
      # Windows CMD
      set REQUESTS_CA_BUNDLE=C:\path\to\your\corporate_ca_bundle.pem
      # Windows PowerShell
      $env:REQUESTS_CA_BUNDLE="C:\path\to\your\corporate_ca_bundle.pem"
    • Configure requests sessions directly in Python:
      import requests

      ca_bundle_path = '/path/to/your/corporate_ca_bundle.pem'
      url = 'https://internal.example.com/api'

      try:
      # Pass the path to the 'verify' parameter
      response = requests.get(url, verify=ca_bundle_path)
      response.raise_for_status()
      print("Request successful using custom CA bundle.")
      except requests.exceptions.SSLError as e:
      print(f"SSL Error with custom CA: {e}")
      except Exception as e:
      print(f"Request failed: {e}")
  • System-wide: You can often add the corporate CA certificate to your operating system's trusted certificate store (see Solution 1 OS-specific details). This is often the best approach in corporate environments.

Solution 4: Check System Time

Ensure your computer's clock is accurately synchronized with a reliable time server. Incorrect time is a common cause of certificate validation failures. Check your OS date and time settings.

Solution 5: Disable SSL Verification (UNSAFE - Last Resort)

warning

Disabling SSL verification defeats the purpose of HTTPS and exposes you to Man-in-the-Middle attacks.

DO NOT do this when connecting to public servers or handling sensitive data unless you fully understand and accept the severe security risks.

Disabling in Pip (--trusted-host)

Using --trusted-host (Solution 2) effectively disables SSL verification for that specific host. There isn't a direct global "disable verify" flag in modern pip for security reasons.

Disabling in requests (verify=False)

import requests
# Suppress only the single InsecureRequestWarning certificate verification generates
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

url = 'https://some.internal.site.with.bad.cert'

try:
# ⚠️ UNSAFE: Disables certificate verification!
response = requests.get(url, verify=False)
print("Request made (verification disabled). Status:", response.status_code)
except Exception as e:
print(f"Request failed: {e}")

Disabling Globally (PYTHONHTTPSVERIFY) - Highly Discouraged

Setting this environment variable disables verification for all HTTPS connections made by standard Python libraries (urllib, potentially affecting requests and pip). Avoid this.

# UNSAFE - For demonstration only
export PYTHONHTTPSVERIFY=0 # Linux/macOS
set PYTHONHTTPSVERIFY=0 # Windows CMD
$env:PYTHONHTTPSVERIFY="0" # Windows PowerShell

General Best Practices (Upgrade Pip, Use Venv)

While not direct fixes for CA issues, following best practices can prevent related problems:

  • Upgrade Pip: Newer versions have better dependency resolution and might include updated certificate handling. python -m pip install --upgrade pip.
  • Use Virtual Environments: Isolate project dependencies (python -m venv venv, activate, install) to avoid system-wide conflicts and ensure consistent library versions (including certifi).

Debugging with Verbose Output (pip -v)

If pip install is failing, run it with increased verbosity to see detailed connection and SSL handshake information:

pip install -v package_name # Or -vv or -vvv for more detail

Look for lines related to SSL, certificate checking, and the URLs being accessed.

Conclusion

The [SSL: CERTIFICATE_VERIFY_FAILED] error means Python could not validate the server's identity using its SSL/TLS certificate.

Key solutions, in order of preference:

  1. Update CA Certificates: Ensure your system and the certifi package (pip install --upgrade certifi) are up-to-date.
  2. Configure Custom CA (Corporate Networks): Use pip --cert, REQUESTS_CA_BUNDLE, or add the corporate CA to your OS trust store if the error is due to proxy/firewall interception.
  3. Use trusted-host (Pip): If connecting to an internal or trusted server where standard verification fails, add it as a trusted-host in pip.conf or via --trusted-host (use cautiously).
  4. Check System Time: Ensure your clock is correct.
  5. Disable Verification: As a last resort and only if security risks are understood and acceptable, use requests(..., verify=False) or --trusted-host. Strongly avoid disabling verification globally.

Prioritize solutions that maintain security (updating CAs, using custom CAs) over disabling verification.