← All tools

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.