boto/boto3 · error · S3UploadFailedError
Failed to upload to /
Error message
Failed to upload {filename} to {bucket}/{key}: {e} What it means
`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.
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.
Example fix
# before
client.upload_file('/tmp/f', 'mybucket', 'key') # raises S3UploadFailedError
# after: surface the underlying error code
from botocore.exceptions import ClientError
from boto3.exceptions import S3UploadFailedError
try:
client.upload_file('/tmp/f', 'mybucket', 'key')
except S3UploadFailedError as e:
cause = e.__cause__ or e
if isinstance(cause, ClientError):
code = cause.response['Error']['Code']
if code == 'AccessDenied':
fix_iam_permissions()
elif code == 'NoSuchBucket':
fix_bucket_name() Defensive patterns
Strategy: try-catch
Validate before calling
# Validate preconditions before uploading
sts = boto3.client('sts')
sts.get_caller_identity() # raises if credentials invalid
region = s3.get_bucket_location(Bucket=bucket)['LocationConstraint']
# ensures credentials + bucket exist before upload_file Type guard
from botocore.exceptions import ClientError
from boto3.exceptions import S3UploadFailedError
def is_access_denied(e) -> bool:
inner = e.__cause__ or e
return isinstance(inner, ClientError) and inner.response['Error']['Code'] == 'AccessDenied' Try / catch
from boto3.exceptions import S3UploadFailedError
from botocore.exceptions import ClientError
try:
client.upload_file(path, bucket, key)
except S3UploadFailedError as e:
cause = e.__cause__ or e
code = cause.response['Error']['Code'] if isinstance(cause, ClientError) else 'Network'
log.error('upload failed (%s): %s', code, cause) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Filename must be a string or a path-like object
- Fileobj must implement read
- CRT transfer client is configured but is missing minimum…
- Either a boto3.Client or s3transfer.manager.TransferManager…
- Fileobj must implement write
AI-assisted analysis of boto/boto3@6e10b029c1 (2026-08-11).
Data as JSON: /api/errors/3dfbb5c6f5ab92a2.
Report an issue: GitHub.
Appendix: source
Thrown at boto3/s3/transfer.py:458
:py:meth:`S3.Client.upload_fileobj`
"""
if isinstance(filename, PathLike):
filename = fspath(filename)
if not isinstance(filename, str):
raise ValueError('Filename must be a string or a path-like object')
subscribers = self._get_subscribers(callback)
future = self._manager.upload(
filename, bucket, key, extra_args, subscribers
)
try:
future.result()
# If a client error was raised, add the backwards compatibility layer
# that raises a S3UploadFailedError. These specific errors were only
# ever thrown for upload_parts but now can be thrown for any related
# client error.
except ClientError as e:
raise S3UploadFailedError(
f"Failed to upload {filename} to {bucket}/{key}: {e}"
)
def download_file(
self, bucket, key, filename, extra_args=None, callback=None
):
"""Download an S3 object to a file.
Variants have also been injected into S3 client, Bucket and Object.
You don't have to use S3Transfer.download_file() directly.
.. seealso::
:py:meth:`S3.Client.download_file`
:py:meth:`S3.Client.download_fileobj`
"""
if isinstance(filename, PathLike):
filename = fspath(filename)
if not isinstance(filename, str):View on GitHub (pinned to 6e10b029c1)