debugjavascriptMajor
S3 CORS blocks browser requests even with correct bucket policy
Viewed 0 times
S3 CORScors configurationAllowedOriginspreflightOPTIONS requestbrowser uploadfetch blocked
Error Messages
Problem
Browser fetch requests to S3 fail with CORS errors despite the bucket appearing correctly configured. The issue is that CORS configuration on S3 is separate from bucket policies and must be set as a dedicated CORSConfiguration on the bucket.
Solution
Set a CORSConfiguration on the S3 bucket (not just the bucket policy). Ensure AllowedOrigins, AllowedMethods, and AllowedHeaders are explicit. For presigned URL uploads, include the headers your client sends in AllowedHeaders.
```json
{
"CORSRules": [
{
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
}
```json
{
"CORSRules": [
{
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
}
Why
S3 CORS is evaluated independently of bucket policies. A bucket policy that allows public reads does not automatically enable CORS. The browser's preflight OPTIONS request must be answered by the CORS configuration.
Gotchas
- Wildcard origin '*' does not work with credentials — use explicit origins when sending auth headers
- CloudFront caches preflight responses — you may need to forward the Origin header and cache based on it
- CORS rules are evaluated in order — the first matching rule wins
- Changing CORS config has eventual consistency — wait a few minutes before testing
- PUT via presigned URL requires the Content-Type header to be included in both the signed headers and AllowedHeaders
Code Snippets
Minimal CORS config for presigned PUT uploads
{
"CORSRules": [
{
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "PUT"],
"AllowedHeaders": ["Content-Type", "x-amz-acl"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
}Context
Building browser-based applications that upload files directly to S3 or fetch S3 resources
Revisions (0)
No revisions yet.