locustio/locust · 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

When `cert` is given as a file path (or (cert, key) tuple), cert_verify assigns conn.cert_file and validates it exists on disk, raising OSError if not. The client cannot perform mutual TLS without the client certificate present.

Source

Thrown at locust/clients.py:524

                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, 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"
    )

View on GitHub (pinned to f391a716e1)

Solutions

  1. Check the cert path exists: `ls -l /path/to/client.crt`
  2. Use absolute paths for cert (and key) files
  3. Ensure secrets/certificates are mounted in containers and readable by the Locust process
  4. Confirm tuple order is (cert, key) when passing a pair

Example fix

// before
self.client.get("/", cert="certs/client.pem")  # relative, missing
// after
self.client.get("/", cert=("/etc/locust/certs/client.crt", "/etc/locust/certs/client.key"))
Defensive patterns

Strategy: validation

Validate before calling

import os
cert_path = "/path/client.crt"
assert os.path.exists(cert_path), f"client cert missing: {cert_path}"

Type guard

def has_client_cert(cert):
    paths = cert if isinstance(cert, (list, tuple)) else [cert]
    return all(os.path.exists(p) for p in paths)

Try / catch

try:
    client.get(url, cert=cert_pair)
except OSError as e:
    logger.error("cert invalid: %s", e)

Prevention

When it happens

Trigger: Passing `cert="/path/to/client.crt"` or `cert=(crt, key)` to FastHttpSession requests where the certificate file path does not exist.

Common situations: mTLS setups where the client cert wasn't deployed to the load-generator; secrets not mounted in Docker/Kubernetes; relative path vs different CWD; permission-restricted paths.

Understand the failure class

Related errors


AI-assisted analysis of locustio/locust@f391a716e1 (2026-08-29). Data as JSON: /api/errors/2b7805d44470ebbf. Report an issue: GitHub.