psf/requests · error · OSError
Could not find the TLS certificate file, invalid path: {conn
Error message
Could not find the TLS certificate file, invalid path: {conn.cert_file} What it means
Raised in HTTPAdapter.cert_verify when a client certificate was supplied via the `cert` parameter but the certificate file path does not exist on disk. requests sets conn.cert_file from either the string form (cert='path.pem') or the first element of the tuple form (cert=('cert.pem','key.pem')) and validates existence before handing the connection to urllib3, failing fast instead of producing an opaque SSL handshake error.
Source
Thrown at src/requests/adapters.py:356
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]
conn.key_file = cert[1]
else:
conn.cert_file = cert
conn.key_file = None
if conn.cert_file and not os.path.exists(conn.cert_file):
raise OSError(
f"Could not find the TLS certificate file, "
f"invalid path: {conn.cert_file}"
)
if conn.key_file and not os.path.exists(conn.key_file):
raise OSError(
f"Could not find the TLS key file, invalid path: {conn.key_file}"
)
def build_response(self, req: PreparedRequest, resp: Any) -> Response:
"""Builds a :class:`Response <requests.Response>` object from a urllib3
response. This should not be called from user code, and is only exposed
for use when subclassing the
:class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
:param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
:param resp: The urllib3 response object.
:rtype: requests.Response
"""View on GitHub ↗ (pinned to 414f0513c3)
Solutions
- Verify the path exists (os.path.exists) and use an absolute path for the client certificate
- Fix the cert tuple order — it must be (cert_file, key_file), not (key, cert)
- In containers/cron, confirm the cert is mounted/deployed at the configured path
- If the key is embedded in the same PEM as the cert, pass a single string path instead of a tuple
Example fix
# before
requests.get(url, cert=('client.crt', 'client.key')) # relative, cwd-dependent
# after
from pathlib import Path
cert_dir = Path(__file__).parent / 'certs'
requests.get(url, cert=(str(cert_dir/'client.crt'), str(cert_dir/'client.key'))) Defensive patterns
Strategy: validation
Validate before calling
import os
cert_file = cert[0] if isinstance(cert, tuple) else cert
if not os.path.isfile(cert_file):
raise FileNotFoundError(f"Client TLS certificate not found: {cert_file}") Try / catch
try:
resp = session.get(url, cert=(cert_file, key_file))
except OSError as e:
raise RuntimeError(f"Client cert path invalid: {cert_file}") from e Prevention
- Check os.path.isfile on the client cert before constructing the session
- Load cert paths from validated config, converting to absolute paths at load time
- Verify file permissions allow the process to read the cert, not just that it exists
When it happens
Trigger: requests.get(url, cert='client.pem') or cert=('client.crt','client.key') where the cert path is wrong or relative to a different working directory; Session.cert set to a stale path. Checked at src/requests/adapters.py:355-359 whenever cert is truthy.
Common situations: Relative cert paths that break when the script runs from a different cwd (cron, systemd, containers); certs mounted into containers at a different path than configured; rotated/expired mTLS certs deleted during renewal; config files referencing another developer's home directory.
Related errors
- Could not find the TLS key file, invalid path: {conn.key_fil
- Could not find a suitable TLS CA certificate bundle, invalid
- Invalid URL {url!r}: No host supplied
- Please check proxy URL. It is malformed and could be missing
- Invalid timeout {timeout}. Pass a (connect, read) timeout tu
AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31).
Data as JSON: /data/errors/f9bbfd4c08da1f98.json.
Report an issue: GitHub ↗.