locustio/locust · error · OSError
Could not find the TLS key file, invalid path
Error message
Could not find the TLS key file, invalid path: {conn.key_file} What it means
When `cert` is a (cert, key) tuple, cert_verify assigns conn.key_file and validates it exists, raising OSError if the key file is missing. Both the cert and its private key must be readable for mTLS to work.
Solutions
- Verify the key path exists: `ls -l /path/client.key`
- Mount the key file (e.g. as a Kubernetes/Docker secret) and use absolute paths
- Check the tuple order: (cert, key), not (key, cert)
- Ensure the Locust process has read permission on the key
Example fix
// before
client.get("/", cert=("/certs/client.crt", "/certs/client.key")) # key not mounted
// after
client.get("/", cert=("/secrets/tls/client.crt", "/secrets/tls/client.key")) # both mounted Defensive patterns
Strategy: validation
Validate before calling
import os
key_path = "/path/client.key"
assert os.path.exists(key_path) and os.access(key_path, os.R_OK), f"TLS key missing/unreadable: {key_path}" Type guard
def has_cert_key_pair(cert):
return (isinstance(cert, (list, tuple)) and len(cert) == 2
and all(os.path.exists(p) for p in cert)) Try / catch
try:
client.get(url, cert=(crt, key))
except OSError as e:
logger.error("TLS key invalid: %s", e) Prevention
- Deploy cert AND key together (same secret)
- Confirm tuple order (cert, key)
- Pre-flight check both files before starting the swarm
When it happens
Trigger: Passing `cert=("/path/client.crt", "/path/client.key")` where the key path does not exist on disk.
Common situations: Deploying only the cert but not the key; key stored in a separate secret not mounted; typos or wrong extension (.pem vs .key); permissions blocking read.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Could not find the TLS certificate file, invalid path
- Could not find a suitable TLS CA certificate bundle…
AI-assisted analysis of locustio/locust@f391a716e1 (2026-08-29).
Data as JSON: /api/errors/cbe3f73d24c03cd4.
Report an issue: GitHub.
Appendix: source
Thrown at locust/clients.py:526
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, 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_connection_pool_key_attributes(self, request, verify, cert=None):
host_params, pool_kwargs = super().build_connection_pool_key_attributes(request, verify, cert)
if requests_version >= (2, 32, 5) and verify is True:
pool_kwargs["ssl_context"] = _preloaded_ssl_context
return host_params, pool_kwargs
# Monkey patch Response class to give some guidance
def _missing_catch_response_True(self, *_args, **_kwargs):
raise LocustError(
"If you want to change the state of the request using .success() or .failure(), you must pass catch_response=True. See http://docs.locust.io/en/stable/writing-a-locustfile.html#validating-responses"
)
Response.success = _missing_catch_response_True # type: ignore[attr-defined]View on GitHub (pinned to f391a716e1)