{"record":{"id":"12994785a9c48d5b","repo":"BerriAI/litellm","slug":"failed-to-download-file-from-s3-s3-uri-error","errorCode":null,"errorMessage":"Failed to download file from S3: {s3_uri}. Error: {e}","messagePattern":"Failed to download file from S3: (.+?)\\. Error: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/bedrock/files/handler.py","lineNumber":133,"sourceCode":"            aws_sts_endpoint=optional_params.get(\"aws_sts_endpoint\"),\n        )\n\n        # Create S3 client\n        s3_client: Final = boto3.client(\n            \"s3\",\n            aws_access_key_id=credentials.access_key,\n            aws_secret_access_key=credentials.secret_key,\n            aws_session_token=credentials.token,\n            region_name=aws_region_name,\n            verify=self._get_ssl_verify(),\n        )\n\n        # Download file from S3\n        try:\n            response: Final = s3_client.get_object(Bucket=bucket_name, Key=object_key)\n            file_content: Final = response[\"Body\"].read()\n        except Exception as e:\n            raise ValueError(f\"Failed to download file from S3: {s3_uri}. Error: {e}\")\n\n        # Create mock HTTP response\n        mock_response: Final = httpx.Response(\n            status_code=200,\n            content=file_content,\n            headers={\"content-type\": \"application/octet-stream\"},\n            request=httpx.Request(method=\"GET\", url=s3_uri),\n        )\n\n        return HttpxBinaryResponseContent(response=mock_response)\n\n    def file_content(\n        self,\n        _is_async: bool,\n        file_content_request: FileContentRequest,\n        api_base: str | None,\n        optional_params: dict,\n        timeout: float | httpx.Timeout,","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/bedrock/files/handler.py#L115-L151","documentation":"While streaming the object from S3 via boto3 get_object, any exception (NoSuchKey, AccessDenied, invalid bucket, network error) is caught and re-raised as ValueError with the s3_uri and underlying error text. The original boto3 error type is lost, but its message is preserved.","triggerScenarios":"GET /files/{id}/content where the object was deleted from the bucket, the credentials lack s3:GetObject, the bucket belongs to another account, or the configured region/endpoint for the S3 client is wrong.","commonSituations":"Lifecycle rules deleting old uploads; wrong AWS_S3_BUCKET_NAME env var pointing at a bucket without the object; cross-account buckets without object ownership/ACL grants; files created before a bucket migration.","solutions":["Read the embedded 'Error: {e}' text — NoSuchKey vs AccessDenied dictates the fix.","Verify the object exists: aws s3 ls <s3_uri> with the same credentials.","Grant s3:GetObject on the bucket/prefix to the role in use.","Confirm AWS_S3_BUCKET_NAME / s3_bucket_name config matches the bucket files were uploaded to."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"def object_exists(s3_client, bucket: str, key: str) -> bool:\n    try:\n        s3_client.head_object(Bucket=bucket, Key=key)\n        return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    content = handler.file_content(request, ...)\nexcept ValueError as e:\n    if \"Failed to download file from S3\" in str(e):\n        if \"NoSuchKey\" in str(e): return HTTP 404\n        if \"AccessDenied\" in str(e): return HTTP 403 / alert\n        raise","preventionTips":["Set S3 lifecycle rules that never delete objects still referenced by stored file ids.","Run periodic reconciliation of stored file ids vs bucket contents.","Test GetObject permissions with the exact runtime role."],"tags":["bedrock","s3","files","aws","permissions"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}