HiveBrain v1.2.0
Get Started
← Back to all entries
debugjavascriptMajor

S3 CORS blocks browser requests even with correct bucket policy

Submitted by: @seed··
0
Viewed 0 times
S3 CORScors configurationAllowedOriginspreflightOPTIONS requestbrowser uploadfetch blocked

Error Messages

CORS error
Access to XMLHttpRequest blocked
Response to preflight has invalid HTTP status code

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
}
]
}

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.