BerriAI/litellm · critical · OCIError
Missing required OCI credentials: oci_user, oci_fingerprint,
Error message
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. What it means
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.
Source
Thrown at litellm/llms/oci/common_utils.py:261
return headers, body
def sign_with_manual_credentials(
headers: dict,
optional_params: dict,
request_data: dict,
api_base: str,
) -> tuple[dict, bytes]:
"""Sign a request using manually provided OCI credentials (user/fingerprint/tenancy/key)."""
creds: Final = resolve_oci_credentials(optional_params)
oci_user: Final = creds["oci_user"]
oci_fingerprint: Final = creds["oci_fingerprint"]
oci_tenancy: Final = creds["oci_tenancy"]
oci_key: Final = creds["oci_key"]
oci_key_file: Final = creds["oci_key_file"]
if not oci_user or not oci_fingerprint or not oci_tenancy or not (oci_key or oci_key_file):
raise OCIError(
status_code=401,
message=(
"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: "
f"{_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."
),
)
method: Final = str(optional_params.get("method", "POST")).upper()
body: Final = json.dumps(request_data).encode("utf-8")
parsed: Final = urlparse(api_base)
path: Final = parsed.path or "/"
host: Final = parsed.netloc
date: Final = formatdate(usegmt=True)
content_type: Final = headers.get("content-type", "application/json")View on GitHub (pinned to 6c2dcb801b)
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.
Example fix
# before litellm.completion(model="oci/cohere.command-r-plus", messages=m) # OCIError 401 # after import os from dotenv import load_dotenv load_dotenv() # sets OCI_USER, OCI_FINGERPRINT, OCI_TENANCY, OCI_KEY_FILE litellm.completion(model="oci/cohere.command-r-plus", messages=m)
Defensive patterns
Strategy: validation
Validate before calling
import os
missing = [
v for v in ("OCI_USER", "OCI_FINGERPRINT", "OCI_TENANCY")
if not os.environ.get(v)
]
has_key = bool(os.environ.get("OCI_KEY") or os.environ.get("OCI_KEY_FILE"))
assert not missing and has_key, f"Missing OCI credentials: {missing}, key={not has_key}" Try / catch
from litellm.llms.oci.common_utils import OCIError
try:
litellm.completion(model="oci/...", messages=m)
except OCIError as e:
if e.status_code == 401 and "Missing required OCI credentials" in str(e):
raise ConfigError("load OCI env vars / pass oci_* params before calling") from e
raise Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- GDC only accepts a GDCH service account credential as a JSON
- The provided private key is not an RSA key, which is require
- Private key file not found: {file_path}
- Private key file is empty: {file_path}
- Private key is required for OCI authentication. Provide eith
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/823978c5c39da8a1.
Report an issue: GitHub.