psf/requests · error · OSError

Could not find a suitable TLS CA certificate bundle…

Error message

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

What it means

Raised during cert_verify when an HTTPS request is made with verify enabled (True or a path) but no readable CA certificate bundle exists at the resolved location. The library resolves cert_loc from an explicit verify path, then falls back to DEFAULT_CA_BUNDLE_PATH (certifi); if the final path is empty or os.path.exists returns False, it raises OSError. This is a pre-connection guard so that urllib3 never proceeds without a trust store.

Solutions

  1. If using verify=True: reinstall certifi (pip install --force-reinstall certifi) so DEFAULT_CA_BUNDLE_PATH resolves.
  2. If verify=<path>: confirm the path exists and is readable with os.path.exists/os.access before passing it.
  3. For PyInstaller/frozen apps: include the certifi bundle, e.g. --add-data "$(python -m certifi);certifi" and reference it via verify=certifi.where().
  4. For container images: install ca-certificates and certifi in the final stage, or COPY the bundle into a stable path and pass verify=that path.
  5. As a temporary diagnostic, set verify=False only to confirm the error source; never leave it disabled for production TLS.

Example fix

# before
requests.get("https://example.com", verify="/etc/ssl/missing-bundle.pem")  # -> OSError

# after
import certifi
requests.get("https://example.com", verify=certifi.where())
Defensive patterns

Strategy: validation

Validate before calling

import os
import certifi

def resolve_ca_bundle(verify):
    """Return a verified-existing CA bundle path, or True for the default."""
    if verify is True or verify is None:
        path = certifi.where()
    elif isinstance(verify, str):
        path = verify
    else:
        return verify  # False
    if not path or not os.path.exists(path):
        raise FileNotFoundError(f"CA bundle not found: {path}")
    return path

# usage
requests.get(url, verify=resolve_ca_bundle(verify_arg))

Type guard

import os

def is_valid_ca_bundle(verify) -> bool:
    if verify is True or verify is None:
        import certifi
        return os.path.exists(certifi.where())
    if verify is False:
        return True
    if isinstance(verify, str):
        return os.path.exists(verify) and os.access(verify, os.R_OK)
    return False

Try / catch

try:
    resp = requests.get(url, verify=verify_path)
except OSError as e:
    if "CA certificate bundle" in str(e):
        # fall back to certifi, or fail loudly
        import certifi
        resp = requests.get(url, verify=certifi.where())
    else:
        raise

Prevention

When it happens

Trigger: Produced when verify=True and the bundled certifi CA file is missing from the install (corrupt or stripped install), or when verify is set to a user-supplied path string that does not exist on the filesystem. Also when DEFAULT_CA_BUNDLE_PATH points at a file removed by an OS package cleanup or a slimmed container image.

Common situations: Happens in distroless/alpine images where certifi data files were pruned, in frozen apps (PyInstaller) that did not include the certifi cacert.pem via --add-data, in air-gapped envs where verify points to an internal CA bundle path that differs across hosts, and after a broken pip install that left certifi partially installed.

Understand the failure class

Related errors


AI-assisted analysis of psf/requests@8068356288 (2026-08-11). Data as JSON: /api/errors/4555c0be2901eb35. Report an issue: GitHub.

Appendix: 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 8068356288)