BerriAI/litellm · error · ValueError
Invalid S3 URI format: {s3_uri}
Error message
Invalid S3 URI format: {s3_uri} What it means
Raised by the Bedrock S3 URI parser when the supplied string does not start with the 's3://' scheme. LiteLLM requires canonical S3 URIs for Bedrock file transformations (document upload for converse APIs), and this is the first structural check. The same message is reused for a second failure where the remainder contains no '/' separator.
Source
Thrown at litellm/llms/bedrock/common_utils.py:1409
if model.startswith("bedrock/"):
return model[8:] # Remove "bedrock/" prefix
return model
def parse_s3_uri(self, s3_uri: str) -> tuple:
"""
Parse S3 URI into bucket and key components.
Args:
s3_uri: S3 URI (e.g., "s3://bucket/key/path")
Returns:
Tuple of (bucket, key)
Raises:
ValueError: If URI format is invalid
"""
if not s3_uri.startswith("s3://"):
raise ValueError(f"Invalid S3 URI format: {s3_uri}")
s3_parts: Final = s3_uri[5:].split("/", 1) # Remove "s3://" and split on first "/"
if len(s3_parts) != 2:
raise ValueError(f"Invalid S3 URI format: {s3_uri}")
return s3_parts[0], s3_parts[1] # bucket, key
def extract_model_from_s3_file_path(self, s3_uri: str, optional_params: dict) -> str:
"""
Extract model ID from S3 file path.
The Bedrock file transformation creates S3 objects with the model name embedded:
Format: s3://bucket/litellm-bedrock-files-{model}-{uuid}.jsonl
"""
# Check if model is provided in optional_params first
if "model" in optional_params and optional_params["model"]:
return self.get_bedrock_model_id_from_litellm_model(optional_params["model"])
View on GitHub (pinned to 6c2dcb801b)
Solutions
- Normalize the URI to the form s3://<bucket>/<key> before passing it to LiteLLM
- If the source is an AWS console link (https://s3.<region>.amazonaws.com/bucket/key), convert it to s3://bucket/key
- Validate user-supplied URIs with a regex or urllib.parse before they reach the Bedrock path
Example fix
// before
await client.messages.create(model=..., files=[{"file_data": "https://s3.us-east-1.amazonaws.com/mybucket/doc.json"}])
// after
await client.messages.create(model=..., files=[{"file_data": "s3://mybucket/doc.json"}]) Defensive patterns
Strategy: validation
Validate before calling
import re
S3_URI_RE = re.compile(r"^s3://[^/]+/.+$")
def is_valid_s3_uri(uri: str) -> bool:
return isinstance(uri, str) and bool(S3_URI_RE.match(uri)) Type guard
def is_s3_uri(value: str) -> bool:
return isinstance(value, str) and value.startswith("s3://") and "/" in value[5:] Try / catch
try:
bucket, key = parse_s3_uri(uri)
except ValueError as e:
raise ValueError(f"Bad file reference '{uri}': expected s3://bucket/key") from e Prevention
- Validate file_data URIs against ^s3://[^/]+/.+$ before sending requests
- Convert AWS console https URLs to s3:// form at ingest time
- Centralize S3 URI construction in one helper so the scheme is never hand-typed
When it happens
Trigger: Passing an http(s) URL, local file path, bare bucket name, or a typo'd scheme (e.g. 'S3://bucket/key' with uppercase) anywhere LiteLLM expects an s3_uri for Bedrock file handling; calling parse on a string like 's3://bucketonly' (no key) hits the sibling check at line 1413.
Common situations: Copying a file URL from the AWS console (which is https), user-supplied file references not validated upstream, or building the URI by string concatenation that drops the scheme.
Related errors
- output_s3_uri cannot be empty for async invoke requests
- file_id is required in file_content_request
- FOCUS_S3_BUCKET_NAME must be provided for S3 exports
- bucket_name must be provided for S3 destination
- Cloud storage bucket name must not include a URI scheme or q
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/5e6c63a49f7edb8d.
Report an issue: GitHub.