Error: 400 Bad Request — Amazon S3 Key Naming Gone Wrong
How a simple space or slash can break your S3 uploads
Problem
You’re uploading to Amazon S3 from your app or CLI, and suddenly —
Error: 400 Bad Request
At first glance, it feels like a generic network or SDK failure. But dig deeper, and the true culprit emerges: your S3 object key name.
Developers often forget that while S3 technically allows almost any Unicode character in object keys, certain patterns and encodings can still trigger a 400 Bad Request. One misplaced slash, space, or unescaped symbol can send the entire PUT request off the rails.
Clarifying the Issue
When you PUT an object to S3, the key (object name) becomes part of the HTTP request path.
For example:
PUT /my-bucket/bad key name.txt HTTP/1.1
That space between bad
and key
looks harmless — but it requires proper URL encoding (%20
) to be valid in the HTTP path.
AWS SDKs usually handle this for you. But if you’re manually constructing requests, generating presigned URLs, or piping data through middleware, a single unescaped character can cause S3 to reject the request with:
400 Bad Request
Common culprits:
- Spaces (
) instead of
%20
- Backslashes (
\
) instead of forward slashes (/
) - Non-UTF-8 characters
- Double slashes (
//
) - Unescaped special characters (
?
,#
,&
,+
)
S3 expects a well-formed HTTP request and assumes the key name is already URL-safe. It won’t fix your encoding for you.
Why It Matters
Bad key naming doesn’t just break uploads — it breaks interoperability.
If your system dynamically generates object names (for user uploads, ETL pipelines, or backups), malformed keys can cause cascading failures:
- Failed PUT/GET requests
- Broken presigned URLs
- Duplicate or missing data in analytics workflows
- Costly retry storms when uploads silently fail
At enterprise scale, a single naming bug can quietly corrupt data integrity and increase operational spend overnight.
Key Terms
S3 Object Key: The full path and name of an object within a bucket (e.g., images/uploads/photo.jpg
).
URL Encoding: Converts unsafe characters into percent-encoded form (e.g., space → %20
).
Presigned URL: A temporary signed link that grants secure, time-limited access to an S3 object.
UTF-8: The required character encoding standard for valid S3 keys.
400 Bad Request: A generic HTTP status meaning the server couldn’t interpret the request — often caused by malformed syntax or encoding errors.
Steps at a Glance
- Inspect the key name before upload.
- Verify URL encoding for all characters.
- Confirm UTF-8 compliance.
- Test with a simple key (e.g.,
test.txt
). - Re-upload using an AWS SDK that handles encoding automatically.
Detailed Steps
Inspect the key name before upload.
Log or print the key string you’re sending. Invisible characters often sneak in through user input or concatenation.
Check for illegal or ambiguous characters.
Replace or encode unsafe characters:
import urllib.parse safe_key = urllib.parse.quote('bad key name.txt', safe='') print(safe_key) # bad%20key%20name.txt
Ensure UTF-8 encoding.
key.encode('utf-8')
If this line throws, you’ve got an invalid character in the key.
Test with a minimal key.
Try uploading a plain key like
test.txt
. If that succeeds, the issue is definitely with your original key format.Leverage SDK auto-encoding.
Let AWS tools do the heavy lifting:
s3.put_object(Bucket='my-bucket', Key='valid-file.txt', Body=b'content')
The SDK encodes, signs, and formats requests according to AWS’s internal HTTP rules.
👉 Pro Tip: Encode Once, Name Once
For Python SDK users (boto3):
from urllib.parse import quote
key = quote("data/2025/Oct/Bad key #1.txt", safe="/")
s3.put_object(Bucket="my-bucket", Key=key, Body=b"data")
For AWS CLI users:
Always wrap keys with quotes and avoid unescaped characters:
aws s3 cp "bad key name.txt" s3://my-bucket/"bad%20key%20name.txt"
Bottom line: Treat S3 keys as URLs, not filenames. Once encoded correctly, leave them alone — double-encoding will break your path again.
Conclusion
S3 is incredibly forgiving — until it isn’t.
A single space or special character can derail an entire workflow and leave your logs full of cryptic 400 Bad Request errors.
The best practice is to enforce key validation early — right where your application generates or accepts object names. Standardize, encode once, and stay consistent.
In cloud engineering, naming isn’t cosmetic — it’s architecture.
Aaron Rose is a software engineer and technology writer at tech-reader.blog and the author of Think Like a Genius.
Comments
Post a Comment