BerriAI/litellm · error · BedrockError

raw_response.text

Error message

raw_response.text

What it means

While transforming the Bedrock S3 GetObject response for /v1/files/<id>/content, LiteLLM checks the HTTP status and, for any status >= 400, raises BedrockError carrying the upstream status code, raw response body (raw_response.text), and headers. The 'message' is literally the S3 error XML/body, e.g. 'AccessDenied' or 'The specified key does not exist'.

Source

Thrown at litellm/llms/bedrock/files/transformation.py:1254

        empty_body_hash: Final = hashlib.sha256(b"").hexdigest()
        aws_request: Final = AWSRequest(  # any-ok: botocore AWSRequest is untyped
            method="GET",
            url=api_base,
            headers={"x-amz-content-sha256": empty_body_hash},
        )
        auth: Final = S3SigV4Auth(credentials, "s3", aws_region_name)  # any-ok: botocore untyped
        auth.add_auth(aws_request)  # any-ok: botocore request mutation is untyped
        return dict(aws_request.headers)  # any-ok: botocore headers are untyped

    def transform_file_content_response(
        self,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
        litellm_params: dict,
    ) -> HttpxBinaryResponseContent:
        if raw_response.status_code >= 400:
            raise BedrockError(
                status_code=raw_response.status_code,
                message=raw_response.text,
                headers=raw_response.headers,
            )
        return HttpxBinaryResponseContent(response=raw_response)


class BedrockJsonlFilesTransformation:
    """
    Transforms OpenAI /v1/files/* requests to Bedrock S3 file uploads for batch processing
    """

    def transform_openai_file_content_to_bedrock_file_content(
        self, openai_file_content: FileTypes | None = None
    ) -> tuple[str, str]:
        """
        Transforms OpenAI FileContentRequest to Bedrock S3 file format
        """

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Read the BedrockError message body — S3 returns '<Code>...</Code>' (e.g. NoSuchKey, AccessDenied) which names the root cause.
  2. For 404/NoSuchKey: re-upload the batch file and use the new file id; check bucket lifecycle rules.
  3. For 403: verify the AWS credentials litellm resolved (env vars, profile, or STS role) have s3:GetObject on that bucket/key prefix.
  4. Confirm bucket region matches aws_region_name used for signing.
Defensive patterns

Strategy: try-catch

Try / catch

from litellm.exceptions import BedrockError

try:
    content = litellm.file_content(file_id=bedrock_file_id)
except BedrockError as e:
    if e.status_code == 404:
        # object gone: re-upload or surface 'not found'
        ...
    elif e.status_code == 403:
        # credentials/bucket perms: alert ops
        ...
    else:
        raise

Prevention

When it happens

Trigger: GET on bedrock://<bucket>/<key> returning 403 (bad credentials / wrong bucket), 404 (object key deleted or never uploaded), or 400 from S3; i.e. any file-content download where S3 rejects the signed request.

Common situations: Expired STS credentials used to sign the GetObject; file id referencing an object removed by a bucket lifecycle rule; cross-region bucket access denied; requesting content for a file uploaded under a different AWS account/profile.

Related errors


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