{"record":{"id":"3dfbb5c6f5ab92a2","repo":"boto/boto3","slug":"failed-to-upload-filename-to-bucket-key-e","errorCode":null,"errorMessage":"Failed to upload {filename} to {bucket}/{key}: {e}","messagePattern":"Failed to upload (.+?) to (.+?)/(.+?): (.+?)","errorType":"exception","errorClass":"S3UploadFailedError","httpStatus":null,"severity":"error","filePath":"boto3/s3/transfer.py","lineNumber":458,"sourceCode":"            :py:meth:`S3.Client.upload_fileobj`\n        \"\"\"\n        if isinstance(filename, PathLike):\n            filename = fspath(filename)\n        if not isinstance(filename, str):\n            raise ValueError('Filename must be a string or a path-like object')\n\n        subscribers = self._get_subscribers(callback)\n        future = self._manager.upload(\n            filename, bucket, key, extra_args, subscribers\n        )\n        try:\n            future.result()\n        # If a client error was raised, add the backwards compatibility layer\n        # that raises a S3UploadFailedError. These specific errors were only\n        # ever thrown for upload_parts but now can be thrown for any related\n        # client error.\n        except ClientError as e:\n            raise S3UploadFailedError(\n                f\"Failed to upload {filename} to {bucket}/{key}: {e}\"\n            )\n\n    def download_file(\n        self, bucket, key, filename, extra_args=None, callback=None\n    ):\n        \"\"\"Download an S3 object to a file.\n\n        Variants have also been injected into S3 client, Bucket and Object.\n        You don't have to use S3Transfer.download_file() directly.\n\n        .. seealso::\n            :py:meth:`S3.Client.download_file`\n            :py:meth:`S3.Client.download_fileobj`\n        \"\"\"\n        if isinstance(filename, PathLike):\n            filename = fspath(filename)\n        if not isinstance(filename, str):","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/boto/boto3/blob/6e10b029c1326a437932a8b24f38af69fd986e15/boto3/s3/transfer.py#L440-L476","documentation":"`S3UploadFailedError` is the backwards-compatibility wrapper that boto3 raises around any `botocore.exceptions.ClientError` occurring during `upload_file`. The underlying ClientError (permissions, no such bucket, signature mismatch, KMS access denied, etc.) is included in the message. It exists so callers historically catching boto3's upload error still work after the implementation moved to s3transfer.","triggerScenarios":"Any AWS-side failure during `client.upload_file` / `bucket.upload_file` / `object.upload_file`: missing/invalid credentials, non-existent bucket, `AccessDenied`/`Forbidden`, KMS key unusable, expired pre-signed URL, or a throttled request that exhausts client retries.","commonSituations":"Wrong region configured for the bucket; IAM principal lacks `s3:PutObject` (or a bucket-policy/KMS denial); stale credentials from a cached profile; a typo in bucket or key name; uploading to a bucket in another account without proper trust/permissions.","solutions":["Inspect `e`'s wrapped error: catch `S3UploadFailedError` and read the inner `ClientError.response['Error']['Code']` to pinpoint the cause.","Verify credentials and region: `aws sts get-caller-identity` and confirm the bucket region with `aws s3api get-bucket-location`.","Confirm the IAM policy grants `s3:PutObject` on `arn:aws:s3:::<bucket>/<key>` (and `kms:GenerateDataKey`/`kms:Decrypt` if SSE-KMS).","Check the bucket name spelling and that it exists in the configured region."],"exampleFix":"# before\nclient.upload_file('/tmp/f', 'mybucket', 'key')  # raises S3UploadFailedError\n\n# after: surface the underlying error code\nfrom botocore.exceptions import ClientError\nfrom boto3.exceptions import S3UploadFailedError\ntry:\n    client.upload_file('/tmp/f', 'mybucket', 'key')\nexcept S3UploadFailedError as e:\n    cause = e.__cause__ or e\n    if isinstance(cause, ClientError):\n        code = cause.response['Error']['Code']\n        if code == 'AccessDenied':\n            fix_iam_permissions()\n        elif code == 'NoSuchBucket':\n            fix_bucket_name()","handlingStrategy":"try-catch","validationCode":"# Validate preconditions before uploading\nsts = boto3.client('sts')\nsts.get_caller_identity()  # raises if credentials invalid\nregion = s3.get_bucket_location(Bucket=bucket)['LocationConstraint']\n# ensures credentials + bucket exist before upload_file","typeGuard":"from botocore.exceptions import ClientError\nfrom boto3.exceptions import S3UploadFailedError\n\ndef is_access_denied(e) -> bool:\n    inner = e.__cause__ or e\n    return isinstance(inner, ClientError) and inner.response['Error']['Code'] == 'AccessDenied'","tryCatchPattern":"from boto3.exceptions import S3UploadFailedError\nfrom botocore.exceptions import ClientError\ntry:\n    client.upload_file(path, bucket, key)\nexcept S3UploadFailedError as e:\n    cause = e.__cause__ or e\n    code = cause.response['Error']['Code'] if isinstance(cause, ClientError) else 'Network'\n    log.error('upload failed (%s): %s', code, cause)","preventionTips":["Verify credentials and region before uploads (sts.get_caller_identity).","Confirm IAM grants s3:PutObject (and KMS perms for SSE-KMS).","Centralize upload error handling to map ClientError codes to fixes."],"tags":["s3","upload","client-error","iam","credentials"],"backgroundTag":null,"analyzedSha":"6e10b029c1326a437932a8b24f38af69fd986e15","analyzedAt":"2026-08-11T20:52:47.213Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}