psf/requests · error · OSError

Could not find a suitable TLS CA certificate bundle, invalid

Error message

Could not find a suitable TLS CA certificate bundle, invalid path: {cert_loc}

What it means

HTTPAdapter.cert_verify raises this OSError when TLS verification is enabled for an https URL but the CA bundle path it resolved does not exist. The path comes either from the user's `verify` argument (when it's a string) or falls back to DEFAULT_CA_BUNDLE_PATH (certifi's bundle); if neither yields an existing file or directory, the request cannot verify the server certificate and requests fails fast rather than connecting insecurely.

Source

Thrown at src/requests/adapters.py:332

        :param conn: The urllib3 connection object associated with the cert.
        :param url: The requested URL.
        :param verify: Either a boolean, in which case it controls whether we verify
            the server's TLS certificate, or a string, in which case it must be a path
            to a CA bundle to use
        :param cert: The SSL certificate to verify.
        """
        if url.lower().startswith("https") and verify:
            cert_loc = None

            # Allow self-specified cert location.
            if verify is not True:
                cert_loc = verify

            if not cert_loc:
                cert_loc = DEFAULT_CA_BUNDLE_PATH

            if not cert_loc or not os.path.exists(cert_loc):
                raise OSError(
                    f"Could not find a suitable TLS CA certificate bundle, "
                    f"invalid path: {cert_loc}"
                )

            conn.cert_reqs = "CERT_REQUIRED"

            if not os.path.isdir(cert_loc):
                conn.ca_certs = cert_loc
            else:
                conn.ca_cert_dir = cert_loc
        else:
            conn.cert_reqs = "CERT_NONE"
            conn.ca_certs = None
            conn.ca_cert_dir = None

        if cert:
            if not isinstance(cert, basestring):
                conn.cert_file = cert[0]

View on GitHub ↗ (pinned to 414f0513c3)

Solutions

  1. Check the path in the error and fix the verify= argument or REQUESTS_CA_BUNDLE/CURL_CA_BUNDLE env var to an existing PEM file
  2. Reinstall certifi (pip install --force-reinstall certifi) if the default bundle is missing
  3. In frozen builds, bundle certifi's cacert.pem and point verify/REQUESTS_CA_BUNDLE at the extracted path
  4. If appending a corporate CA, concatenate it with certifi's bundle into a file that actually exists and pass that path

Example fix

# before
requests.get(url, verify='/etc/ssl/corp-ca.pem')  # file not mounted -> OSError

# after
import certifi, os
bundle = os.environ.get('REQUESTS_CA_BUNDLE', certifi.where())
requests.get(url, verify=bundle)
Defensive patterns

Strategy: validation

Validate before calling

import os
cert_loc = verify_path  # value passed as verify= or REQUESTS_CA_BUNDLE
if isinstance(cert_loc, str) and not os.path.exists(cert_loc):
    raise FileNotFoundError(f"CA bundle not found: {cert_loc}")

Try / catch

try:
    resp = session.get(url, verify=ca_bundle_path)
except OSError as e:
    # requests raises OSError('Could not find a suitable TLS CA certificate bundle...')
    raise RuntimeError(f"CA bundle path invalid: {ca_bundle_path}") from e

Prevention

When it happens

Trigger: requests.get('https://...', verify='/path/to/ca.pem') with a wrong or nonexistent path; REQUESTS_CA_BUNDLE or CURL_CA_BUNDLE env vars pointing to a missing file; certifi missing or its cacert.pem stripped (DEFAULT_CA_BUNDLE_PATH invalid). Raised at src/requests/adapters.py:331-335 only for https URLs with verify truthy.

Common situations: Frozen apps (PyInstaller/cx_Freeze) that don't package certifi's cacert.pem; Docker images or CI where REQUESTS_CA_BUNDLE points at a corporate CA file that isn't mounted; typo'd verify= paths; corporate-proxy setups where the internal CA bundle path differs between machines; broken certifi installs after aggressive site-packages pruning.

Related errors


AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31). Data as JSON: /data/errors/4555c0be2901eb35.json. Report an issue: GitHub ↗.