Skip to main content

Applying CORS policies

By default, browsers block requests from a website (https://app.example.com) to a different origin such as https://Bucketname.s3.internet1.de. By setting up a CORS configuration on the bucket, you can specifically allow such cross-origin access – for example, for direct uploads from the browser or for loading fonts and media via JavaScript.

When do I need CORS?​

  • fetch()/XMLHttpRequest processing of objects from the browser (including with pre-signed URLs)
  • Browser uploads directly to the bucket (pre-signed PUT/POST)
  • Web fonts, WebGL textures, <canvas> processing of images from the bucket

CORS is not required for server-side access (CLI, back-end SDKs) or simple integration via <img src=…>.

Setting CORS rules​

cors.json:

{
"CORSRules": [
{
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "HEAD", "PUT"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]
}
aws s3api put-bucket-cors --bucket mein-bucket \
--cors-configuration file://cors.json \
--endpoint-url https://s3.internet1.de

Fields at a glance​

FieldMeaning
AllowedOriginsPermitted origins (scheme + host + port). * permits all – use only for public, non-critical content.
AllowedMethodsGET, HEAD, PUT, POST, DELETE
AllowedHeadersHeaders that the browser is permitted to send (e.g. Content-Type, x-amz-*); * for all
ExposeHeadersResponse headers that JavaScript is permitted to read – ETag is required for multipart uploads in the browser
MaxAgeSecondsCache duration of the preflight response in the browser

Several rules are possible; the first one that fits wins.

Check and remove the configuration​

aws s3api get-bucket-cors --bucket mein-bucket --endpoint-url https://s3.internet1.de
aws s3api delete-bucket-cors --bucket mein-bucket --endpoint-url https://s3.internet1.de

Testing CORS​

Simulate a pre-flight request:

curl -i -X OPTIONS "https://mein-bucket.s3.internet1.de/test.txt" \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: PUT"

If the rule applies, the answer includes, amongst other things, Access-Control-Allow-Origin: https://app.example.com.

Common mistakes​

SymptomCauseSolution
Console reports blocked by CORS policyOrigin not in AllowedOriginsEnter the exact origin (including https://, without the path, and the port if applicable)
PUT upload fails, GET worksPUT missing from AllowedMethods or Content-Type not in AllowedHeadersAdd method/header
Multipart upload in the browser hangs after partsETag not in ExposeHeadersSet "ExposeHeaders": ["ETag"]
Change does not take effect immediatelyPreflight cached in the browserWait for MaxAgeSeconds or try a hard reload/incognito mode
Safety

CORS is not an access control mechanism, but merely a browser-based authorisation mechanism. Private objects remain protected by ACLs and signatures – conversely, a restrictive CORS rule does not protect public objects from being downloaded outside the browser.