BerriAI/litellm · error · OCIError
Failed to sign request with provided oci_signer: {e}. The si
Error message
Failed to sign request with provided oci_signer: {e}. The signer must implement the OCI SDK Signer interface with a do_request_sign(request, enforce_content_headers=True) method. See: https://docs.oracle.com/en-us/iaas/tools/python/latest/api/signing.html What it means
When an oci_signer object is supplied, litellm calls signer.do_request_sign(request, enforce_content_headers=True) inside a broad except Exception and rewraps any failure as OCIError(500) explaining the expected OCI SDK Signer interface. It fires when the provided object does not behave like an OCI SDK Signer or rejects the request wrapper.
Source
Thrown at litellm/llms/oci/common_utils.py:232
body: Final = json.dumps(request_data).encode("utf-8")
method: Final = str(optional_params.get("method", "POST")).upper()
if method not in {"POST", "GET", "PUT", "DELETE", "PATCH"}:
raise ValueError(f"Unsupported HTTP method: {method}")
prepared_headers: Final = {**headers}
prepared_headers.setdefault("content-type", "application/json")
prepared_headers.setdefault("content-length", str(len(body)))
request_wrapper: Final = OCIRequestWrapper(method=method, url=api_base, headers=prepared_headers, body=body)
if oci_signer is None:
raise ValueError("oci_signer cannot be None when calling sign_with_oci_signer")
try:
oci_signer.do_request_sign(request_wrapper, enforce_content_headers=True)
except Exception as e:
raise OCIError(
status_code=500,
message=(
f"Failed to sign request with provided oci_signer: {e}. "
"The signer must implement the OCI SDK Signer interface with a "
"do_request_sign(request, enforce_content_headers=True) method. "
"See: https://docs.oracle.com/en-us/iaas/tools/python/latest/api/signing.html"
),
) from e
headers.update(request_wrapper.headers)
return headers, body
def sign_with_manual_credentials(
headers: dict,
optional_params: dict,
request_data: dict,
api_base: str,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Build the signer exactly as the OCI SDK documents: oci.signer.Signer(tenancy, user, fingerprint, private_key_file_path, ...).
- Upgrade/pin the oci package to a version whose Signer interface matches (do_request_sign(request, enforce_content_headers=True)).
- In tests, mock at the HTTP layer instead of passing a fake signer into production code paths.
- Check the embedded original exception text ({e}) — it names the actual attribute/signature mismatch.
Example fix
# before
optional_params["oci_signer"] = lambda req: None # OCIError(500)
# after
import oci
optional_params["oci_signer"] = oci.signer.Signer(
tenancy=os.environ["OCI_TENANCY"],
user=os.environ["OCI_USER"],
fingerprint=os.environ["OCI_FINGERPRINT"],
private_key_file_path=os.environ["OCI_KEY_FILE"],
) Defensive patterns
Strategy: try-catch
Validate before calling
signer = optional_params.get("oci_signer")
assert signer is not None and callable(getattr(signer, "do_request_sign", None)), \
"oci_signer must implement do_request_sign(request, enforce_content_headers=True)" Type guard
from typing import Any, Protocol
class OCISignerLike(Protocol):
def do_request_sign(self, request: Any, enforce_content_headers: bool = ...) -> None: ...
def is_valid_oci_signer(obj: Any) -> bool:
return callable(getattr(obj, "do_request_sign", None)) Try / catch
from litellm.llms.oci.common_utils import OCIError
try:
litellm.completion(model="oci/...", messages=m)
except OCIError as e:
if "Failed to sign request with provided oci_signer" in str(e):
raise ConfigError("oci_signer is not an OCI SDK Signer — rebuild with oci.signer.Signer(...)") from e
raise Prevention
- Construct signers only via the official oci SDK (oci.signer.Signer / instance_principals_signer).
- Pin the oci package version and test the signer against the real endpoint in CI.
- Never substitute mocks or lambdas for the signer in production paths.
When it happens
Trigger: Passing a plain function, a mock, a dataclass, or an object from an incompatible oci SDK version whose do_request_sign has a different signature; a signer whose credentials are incomplete so signing itself throws; a signer subclass overriding do_request_sign with extra required kwargs.
Common situations: Users constructing signers manually (security_token_signer, instance_principals_signer) across oci SDK versions; test doubles replacing the signer; copy-pasted code building oci.signer.Signer(...) with tenancy/user/fingerprint/key_file misordered, causing an internal exception during signing.
Related errors
- Unsupported HTTP method: {method}
- Unexpected string response from Azure: {response[:500]}
- azure_client is not an instance of AzureOpenAI
- Response cannot be casted to CohereChatResult: {e}
- Chunk cannot be parsed as CohereStreamChunk: {e}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/d916f79371630b19.
Report an issue: GitHub.