S3 CORS Rule Tester
Paste your bucket's CORS configuration (the JSON from
aws s3api get-bucket-cors, or the XML
<CORSConfiguration> block), describe a request,
and see exactly which rule matches, what headers S3 will send
back, and whether the browser will actually accept the response —
the part curl and the S3 console won't tell you.
Why does my S3 CORS config work in curl but fail in the browser?
curl doesn't enforce CORS at all — it just shows you whatever
headers S3 sends back. The browser separately checks the
Access-Control-Allow-Origin value against the
page's own origin, and for credentialed requests, rejects a
literal * value even though S3 returned 200 OK.
This tool reproduces the browser's matching logic, not just the
raw HTTP response.
Why doesn't AllowedOrigins: https://*.example.com match https://example.com?
The wildcard in an S3 CORS AllowedOrigin is a
literal substring wildcard, not a subdomain-or-root pattern.
https://*.example.com requires at least the dot and
something before it, so it matches
https://app.example.com but not the bare root
domain https://example.com. You need a second,
explicit AllowedOrigins entry for the root domain
if you want both.
Why can my JS not read a custom S3 response header even though the request succeeds?
By default, browsers only expose a small safelist of response
headers to JavaScript (Cache-Control,
Content-Language, Content-Length,
Content-Type, Expires,
Last-Modified, Pragma). Any other
header, including S3's own x-amz-* headers,
returns null from
response.headers.get() unless it's explicitly
listed in the CORS rule's ExposeHeaders. The
request itself still returns 200 OK, which is what makes this
bug so easy to miss.
Does this tool upload my CORS configuration anywhere?
No. Everything runs in your browser with plain JavaScript. Nothing you paste is sent to a server.