psf/requests · error · OSError
Could not find the TLS certificate file, invalid path
Error message
Could not find the TLS certificate file, invalid path: {conn.cert_file} What it means
Raised during cert_verify when a client certificate is supplied (cert=...) but the resolved certificate file path does not exist on disk. The cert argument may be a single path string or a (cert, key) tuple; conn.cert_file is set from it and then os.path.exists is checked. A missing file aborts before the TLS handshake so the failure is surfaced as a config error rather than an opaque SSL error.
Solutions
- Check the path exists with os.path.exists before passing it as cert; resolve it to an absolute path first.
- Confirm the file is readable by the process user (permissions, mount, volume).
- For containerized apps: verify the secret/configmap is mounted at the exact path and the mount is not read-only-missing.
- If using a tuple, ensure the cert file is the first element and the key the second.
- In CI, fail fast by asserting the cert path during startup health checks rather than at first request.
Example fix
# before
session.cert = "/etc/secrets/client.crt" # file absent -> OSError
# after
import os
cert_path = os.path.abspath("/etc/secrets/client.crt")
assert os.path.exists(cert_path), f"client cert missing: {cert_path}"
session.cert = cert_path Defensive patterns
Strategy: validation
Validate before calling
import os
def resolve_client_cert(cert):
"""Validate cert arg; return it unchanged if the file(s) exist."""
if cert is None:
return None
if isinstance(cert, str):
if not os.path.exists(cert):
raise FileNotFoundError(f"client cert not found: {cert}")
elif isinstance(cert, (tuple, list)):
for p in cert:
if not os.path.exists(p):
raise FileNotFoundError(f"cert file not found: {p}")
else:
raise TypeError(f"unsupported cert type: {type(cert)}")
return cert
session.cert = resolve_client_cert(config["client_cert"]) Type guard
import os
def is_valid_client_cert(cert) -> bool:
if cert is None:
return True
if isinstance(cert, str):
return os.path.exists(cert) and os.access(cert, os.R_OK)
if isinstance(cert, (tuple, list)) and len(cert) == 2:
return all(os.path.exists(p) and os.access(p, os.R_OK) for p in cert)
return False Try / catch
try:
resp = session.get(url)
except OSError as e:
if "TLS certificate file" in str(e):
# re-check the path, log, and surface a clear config error
raise RuntimeError(f"client cert path invalid: {session.cert}") from e
raise Prevention
- Mount mTLS secrets at stable, documented paths; assert existence at startup.
- Use absolute paths for cert files to avoid working-directory surprises.
- Keep cert and key in the same secret volume to avoid partial deploys.
- Rotate certs with a deploy that updates both path and contents together.
When it happens
Trigger: Triggered by passing cert="/path/client.pem" (or cert=("/path/client.crt", "/path/client.key")) where the first element does not exist, in calls to request/get/post or when configuring an HTTPAdapter/Session with a cert. Fires for both the single-string and tuple forms once conn.cert_file is non-empty.
Common situations: Common with mTLS clients where the cert path is environment-specific and the value was hardcoded, when a deployment mounts secrets at a different path than the code expects, when relative paths are resolved against an unexpected working directory, or after secret rotation replaced the file with a new name.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Could not find the TLS key file, invalid path
- Could not find a suitable TLS CA certificate bundle…
- Invalid timeout . Pass a (connect, read) timeout tuple, or…
- Please check proxy URL. It is malformed and could be…
- Unsupported event specified, with event name
AI-assisted analysis of psf/requests@8068356288 (2026-08-11).
Data as JSON: /api/errors/f9bbfd4c08da1f98.
Report an issue: GitHub.
Appendix: 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 8068356288)