{"record":{"id":"ef271d814c2d7d43","repo":"BerriAI/litellm","slug":"private-key-file-is-empty-file-path","errorCode":null,"errorMessage":"Private key file is empty: {file_path}","messagePattern":"Private key file is empty: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"litellm/llms/oci/common_utils.py","lineNumber":138,"sourceCode":"        password=None,\n    )\n    if not isinstance(key, rsa.RSAPrivateKey):\n        raise TypeError(\"The provided private key is not an RSA key, which is required for OCI signing.\")\n    return key\n\n\ndef load_private_key_from_file(file_path: str) -> Any:\n    \"\"\"Loads a private key from a file path.\"\"\"\n    try:\n        with open(file_path, \"r\", encoding=\"utf-8\") as f:\n            key_str: Final = f.read().strip()\n    except FileNotFoundError:\n        raise FileNotFoundError(f\"Private key file not found: {file_path}\")\n    except OSError as e:\n        raise OSError(f\"Failed to read private key file '{file_path}': {e}\") from e\n\n    if not key_str:\n        raise ValueError(f\"Private key file is empty: {file_path}\")\n\n    return load_private_key_from_str(key_str)\n\n\n# ---------------------------------------------------------------------------\n# Env-var credential resolution\n# ---------------------------------------------------------------------------\n\n_OCI_REGION_ENV: Final = \"OCI_REGION\"\n_OCI_USER_ENV: Final = \"OCI_USER\"\n_OCI_FINGERPRINT_ENV: Final = \"OCI_FINGERPRINT\"\n_OCI_TENANCY_ENV: Final = \"OCI_TENANCY\"\n_OCI_KEY_FILE_ENV: Final = \"OCI_KEY_FILE\"\n_OCI_KEY_ENV: Final = \"OCI_KEY\"\n_OCI_COMPARTMENT_ID_ENV: Final = \"OCI_COMPARTMENT_ID\"\n\n\ndef resolve_oci_credentials(optional_params: dict) -> dict:","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/oci/common_utils.py#L120-L156","documentation":"After successfully opening the key file, load_private_key_from_file checks that its content is non-empty (after strip) and raises ValueError naming the path if not. An empty file means the credential was never actually written — typically a truncated provisioning step.","triggerScenarios":"Kubernetes Secret or Docker secret created from an empty/failed command (kubectl create secret with a wrong --from-file); CI writing the key via an unset env var (> key.pem with empty $OCI_KEY); placeholder file committed with no content.","commonSituations":"CI pipelines doing echo \"$OCI_KEY\" > key.pem where the variable is empty in the CI environment; secret templates rendered before the vault lookup; an interrupted key-generation step leaving a zero-byte file; a .gitkeep-style placeholder accidentally referenced.","solutions":["Inspect the file: wc -c <keyfile> and head it — expect ~1700+ bytes of PEM for RSA-2048.","Regenerate the secret/CI step from the real PEM source and guard against empty values: test -s key.pem || exit 1.","In CI, fail fast when the key variable is unset: : \"${OCI_KEY:?OCI_KEY missing}\".","Store the PEM in a proper secret manager instead of shell redirection."],"exampleFix":"# before (CI step that can silently write an empty file)\nrun: echo \"$OCI_KEY\" > /secrets/oci_key.pem\n\n# after\nrun: |\n  test -n \"$OCI_KEY\" || { echo \"OCI_KEY empty\"; exit 1; }\n  printf '%s\\n' \"$OCI_KEY\" > /secrets/oci_key.pem","handlingStrategy":"validation","validationCode":"import os\np = os.path.expanduser(os.environ[\"OCI_KEY_FILE\"])\nassert os.path.getsize(p) > 1000, f\"key file too small ({os.path.getsize(p)} bytes) — likely truncated/empty\"","typeGuard":null,"tryCatchPattern":"try:\n    litellm.completion(model=\"oci/...\", messages=m)\nexcept ValueError as e:\n    if \"Private key file is empty\" in str(e):\n        raise ProvisioningError(\"re-create the secret from the real PEM\") from e\n    raise","preventionTips":["In CI/secret provisioning, fail when the source value is empty (test -n / test -s).","Size-check key files during deployment validation.","Pull keys from a real secret manager rather than shell redirection."],"tags":["oci","authentication","secrets","ci","configuration"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}