{"id":"b4a8a0373582a990","repo":"psf/requests","slug":"could-not-find-the-tls-key-file-invalid-path-co","errorCode":null,"errorMessage":"Could not find the TLS key file, invalid path: {conn.key_file}","messagePattern":"Could not find the TLS key file, invalid path: (.+?)","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"src/requests/adapters.py","lineNumber":361,"sourceCode":"        else:\n            conn.cert_reqs = \"CERT_NONE\"\n            conn.ca_certs = None\n            conn.ca_cert_dir = None\n\n        if cert:\n            if not isinstance(cert, basestring):\n                conn.cert_file = cert[0]\n                conn.key_file = cert[1]\n            else:\n                conn.cert_file = cert\n                conn.key_file = None\n            if conn.cert_file and not os.path.exists(conn.cert_file):\n                raise OSError(\n                    f\"Could not find the TLS certificate file, \"\n                    f\"invalid path: {conn.cert_file}\"\n                )\n            if conn.key_file and not os.path.exists(conn.key_file):\n                raise OSError(\n                    f\"Could not find the TLS key file, invalid path: {conn.key_file}\"\n                )\n\n    def build_response(self, req: PreparedRequest, resp: Any) -> Response:\n        \"\"\"Builds a :class:`Response <requests.Response>` object from a urllib3\n        response. This should not be called from user code, and is only exposed\n        for use when subclassing the\n        :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`\n\n        :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.\n        :param resp: The urllib3 response object.\n        :rtype: requests.Response\n        \"\"\"\n        assert _is_prepared(req)\n        response = Response()\n\n        # Fallback to None if there's no status_code, for whatever reason.\n        response.status_code = getattr(resp, \"status\", None)  # type: ignore[assignment]","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/psf/requests/blob/414f0513c33883adf6f2b46901d4f0b38a455851/src/requests/adapters.py#L343-L379","documentation":"The companion check to error 22: when `cert` is given as a (cert_file, key_file) tuple, HTTPAdapter.cert_verify verifies the private key path exists and raises this OSError if it doesn't. It only fires for the tuple form, since the string form sets key_file to None (key assumed to be in the same PEM).","triggerScenarios":"requests.get(url, cert=('client.crt','client.key')) where the key path is missing, misspelled, or unreadable-by-path; swapping tuple elements so the 'key' slot holds a nonexistent path. Raised at src/requests/adapters.py:360-363.","commonSituations":"Private keys deliberately excluded from repos/images (correctly gitignored) and never provisioned to the runtime; key files with restrictive locations (/etc/ssl/private) referenced from a non-root process using a wrong path; cert renewal tooling writing the new key under a different filename.","solutions":["Confirm the key file exists at the given absolute path and the tuple order is (cert, key)","Provision the private key to the runtime environment (secret mount, deploy step) — it's often intentionally absent from the artifact","If cert and key are combined in one PEM, pass that single path as a string instead of a tuple"],"exampleFix":"# before\nrequests.get(url, cert=('client.crt', 'client.key'))  # key never deployed\n\n# after — combined PEM shipped via secret mount\nrequests.get(url, cert='/run/secrets/client-combined.pem')","handlingStrategy":"validation","validationCode":"import os\nif isinstance(cert, tuple):\n    key_file = cert[1]\n    if not os.path.isfile(key_file):\n        raise FileNotFoundError(f\"Client TLS key not found: {key_file}\")","typeGuard":null,"tryCatchPattern":"try:\n    resp = session.get(url, cert=(cert_file, key_file))\nexcept OSError as e:\n    raise RuntimeError(f\"Client key path invalid: {key_file}\") from e","preventionTips":["Validate both members of the (cert, key) tuple together before any request","Keep cert and key deployment in one step so they cannot drift apart","Fail fast at startup rather than on the first TLS request"],"tags":["tls","client-certificates","mtls","configuration","python"],"analyzedSha":"414f0513c33883adf6f2b46901d4f0b38a455851","analyzedAt":"2026-07-31T19:24:57.696Z","schemaVersion":2}