{"record":{"id":"823978c5c39da8a1","repo":"BerriAI/litellm","slug":"missing-required-oci-credentials-oci-user-oci-fi","errorCode":null,"errorMessage":"Missing required OCI credentials: oci_user, oci_fingerprint, oci_tenancy, and at least one of oci_key or oci_key_file. These can also be supplied via environment variables: {_OCI_USER_ENV}, {_OCI_FINGERPRINT_ENV}, {_OCI_TENANCY_ENV}, {_OCI_KEY_ENV} (or {_OCI_KEY_FILE_ENV}). Alternatively, provide an oci_signer object from the OCI SDK.","messagePattern":"Missing required OCI credentials: oci_user, oci_fingerprint, oci_tenancy, and at least one of oci_key or oci_key_file\\. These can also be supplied via environment variables: (.+?), (.+?), (.+?), (.+?) \\(or (.+?)\\)\\. Alternatively, provide an oci_signer object from the OCI SDK\\.","errorType":"exception","errorClass":"OCIError","httpStatus":401,"severity":"critical","filePath":"litellm/llms/oci/common_utils.py","lineNumber":261,"sourceCode":"    return headers, body\n\n\ndef sign_with_manual_credentials(\n    headers: dict,\n    optional_params: dict,\n    request_data: dict,\n    api_base: str,\n) -> tuple[dict, bytes]:\n    \"\"\"Sign a request using manually provided OCI credentials (user/fingerprint/tenancy/key).\"\"\"\n    creds: Final = resolve_oci_credentials(optional_params)\n    oci_user: Final = creds[\"oci_user\"]\n    oci_fingerprint: Final = creds[\"oci_fingerprint\"]\n    oci_tenancy: Final = creds[\"oci_tenancy\"]\n    oci_key: Final = creds[\"oci_key\"]\n    oci_key_file: Final = creds[\"oci_key_file\"]\n\n    if not oci_user or not oci_fingerprint or not oci_tenancy or not (oci_key or oci_key_file):\n        raise OCIError(\n            status_code=401,\n            message=(\n                \"Missing required OCI credentials: oci_user, oci_fingerprint, oci_tenancy, \"\n                \"and at least one of oci_key or oci_key_file. \"\n                \"These can also be supplied via environment variables: \"\n                f\"{_OCI_USER_ENV}, {_OCI_FINGERPRINT_ENV}, {_OCI_TENANCY_ENV}, {_OCI_KEY_ENV} (or {_OCI_KEY_FILE_ENV}). \"\n                \"Alternatively, provide an oci_signer object from the OCI SDK.\"\n            ),\n        )\n\n    method: Final = str(optional_params.get(\"method\", \"POST\")).upper()\n    body: Final = json.dumps(request_data).encode(\"utf-8\")\n    parsed: Final = urlparse(api_base)\n    path: Final = parsed.path or \"/\"\n    host: Final = parsed.netloc\n\n    date: Final = formatdate(usegmt=True)\n    content_type: Final = headers.get(\"content-type\", \"application/json\")","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/oci/common_utils.py#L243-L279","documentation":"sign_with_manual_credentials resolves credentials from optional_params plus OCI_USER/OCI_FINGERPRINT/OCI_TENANCY/OCI_KEY(_FILE) env vars and raises OCIError(401) listing every missing field when user, fingerprint, tenancy, or a key source is absent. It is the guard before any signing can happen without an oci_signer.","triggerScenarios":"First OCI call in a fresh environment where none of the OCI_* env vars are set and no oci_user/oci_fingerprint/oci_tenancy/oci_key(Key_file) were passed via optional_params or the OCI config file.","commonSituations":"Local dev works (env vars in shell) but deployed container/CI lacks them; env vars set with wrong names (e.g. OCI_API_KEY instead of OCI_KEY); .env file not loaded by the process; credentials passed to litellm.completion in the wrong argument so they never reach optional_params.","solutions":["Set OCI_USER, OCI_FINGERPRINT, OCI_TENANCY and either OCI_KEY (inline PEM) or OCI_KEY_FILE — or pass oci_user/oci_fingerprint/oci_tenancy/oci_key_file via extra_body/optional params.","Verify inside the failing process: print({k: bool(os.environ.get(k)) for k in ('OCI_USER','OCI_FINGERPRINT','OCI_TENANCY','OCI_KEY','OCI_KEY_FILE')}).","Ensure the .env file is actually loaded (python-dotenv) in the deployment.","If you use an OCI SDK signer or instance principals instead, pass oci_signer and skip manual credentials."],"exampleFix":"# before\nlitellm.completion(model=\"oci/cohere.command-r-plus\", messages=m)  # OCIError 401\n\n# after\nimport os\nfrom dotenv import load_dotenv\nload_dotenv()  # sets OCI_USER, OCI_FINGERPRINT, OCI_TENANCY, OCI_KEY_FILE\nlitellm.completion(model=\"oci/cohere.command-r-plus\", messages=m)","handlingStrategy":"validation","validationCode":"import os\nmissing = [\n    v for v in (\"OCI_USER\", \"OCI_FINGERPRINT\", \"OCI_TENANCY\")\n    if not os.environ.get(v)\n]\nhas_key = bool(os.environ.get(\"OCI_KEY\") or os.environ.get(\"OCI_KEY_FILE\"))\nassert not missing and has_key, f\"Missing OCI credentials: {missing}, key={not has_key}\"","typeGuard":null,"tryCatchPattern":"from litellm.llms.oci.common_utils import OCIError\ntry:\n    litellm.completion(model=\"oci/...\", messages=m)\nexcept OCIError as e:\n    if e.status_code == 401 and \"Missing required OCI credentials\" in str(e):\n        raise ConfigError(\"load OCI env vars / pass oci_* params before calling\") from e\n    raise","preventionTips":["Validate all OCI_* env vars in a startup preflight check.","Load .env explicitly in the deployed process and verify with a debug dump of variable names (not values).","Keep one credential-loading module shared by all OCI calls."],"tags":["oci","authentication","credentials","environment","configuration"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}