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

  1. 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.
  2. 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')}).
  3. Ensure the .env file is actually loaded (python-dotenv) in the deployment.
  4. 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

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


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/823978c5c39da8a1. Report an issue: GitHub.