GetBucketCors
GetBucketCors returns a bucket's CORS configuration - every rule, as an XML CORSConfiguration
document. Rules saved in the dashboard and rules set with PutBucketCors are
the same rules, so this operation returns both. CORS rules explains what the
rules do and how a browser uses them.
- Rules come back in a tidy, consistent form: without an
ID, with origins and header names lowercased, and with methods possibly in a different order from the one they were sent in. - Every access key can read the CORS rules of the buckets it reaches - no extra permission needed.
x-amz-expected-bucket-owneris welcome and has nothing to check.
When you'd use it
- A deploy script is about to add a new origin, say a staging site. PutBucketCors replaces every rule at once, so the script reads the current rules first, adds the new origin and writes the full set back.
- A browser upload starts failing with a CORS error. Reading the bucket's rules shows straight away whether the page's origin, method and headers are on the list.
- An agent looking after several buckets checks which websites can reach each one from a browser, and reports any bucket whose rules allow every origin.
- A team keeps its bucket configuration in version control, and a nightly job compares the rules in the repository with the ones the bucket actually has.
Request
GET /?cors HTTP/1.1
Host: my-bucket.s3.eu-central-1.strg.com
Authorization: AWS4-HMAC-SHA256 Credential=...
x-amz-date: 20260926T120000Z
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Path-style, the same request is GET /my-bucket?cors on s3.eu-central-1.strg.com.
Addressing describes both styles.
Permissions
Every access key can call this: Read bucket settings (buckets:read-config) is always
included. A key limited to certain buckets reads the rules of those buckets, and gets
403 AccessDenied for any other. Access keys has the details.
URI parameters
| Name | Type | Required | Description |
|---|---|---|---|
Bucket | String | Yes | The bucket whose CORS configuration is returned. |
cors | Flag | Yes | Selects the CORS subresource. Sent without a value. |
STRG answers any other query parameter with 501 NotImplemented, so a client knows straight
away that the request was not what it meant.
Request headers
| Name | Type | Required | Description |
|---|---|---|---|
x-amz-expected-bucket-owner | String | No | Welcome, and has nothing to check: an access key only ever reaches its own account's buckets. |
Request body
None.
Response
A bucket with CORS rules answers 200 OK with the configuration. A bucket without any answers
404 NoSuchCORSConfiguration, which the AWS SDKs recognise by that code.
Response headers
| Name | Description |
|---|---|
Content-Type | application/xml. |
x-amz-request-id | The request ID, for support requests. |
Response body
The document holds one CORSRule element per rule, each made up of the elements below.
| Element | Type | Description |
|---|---|---|
CORSConfiguration | Container | The root element. |
CORSRule | Container | One rule, repeated for each. At most 100. |
AllowedOrigin | String | An origin the rule allows, lowercased. One element per origin. |
AllowedMethod | String | A method the rule allows: GET, HEAD, PUT, POST or DELETE. One element per method, in no guaranteed order. |
AllowedHeader | String | A request header the rule allows, lowercased. One element per header; absent if the rule allows none. |
ExposeHeader | String | A response header browsers may expose to scripts, lowercased. One element per header; absent if the rule names none. |
MaxAgeSeconds | Integer | How long a browser may cache the preflight answer, in seconds. Absent if the rule sets none. |
ID | String | Never returned: STRG sets rule IDs aside when the rules are saved. |
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>https://www.example.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>etag</ExposeHeader>
<MaxAgeSeconds>3600</MaxAgeSeconds>
</CORSRule>
</CORSConfiguration>
Errors
These are the errors this operation can answer, and the situation behind each.
| Code | HTTP status | When |
|---|---|---|
NoSuchCORSConfiguration | 404 | The bucket has no CORS rules. |
NoSuchBucket | 404 | The bucket does not exist, it is in a region other than the endpoint's, or your account has no storage in this endpoint's region yet. |
AccessDenied | 403 | The access key is limited to buckets that do not include this one, or your account is not active. |
InvalidAccessKeyId | 403 | The access key does not exist, has expired or been revoked, or was created so recently that it is not yet usable in this endpoint's region - a moment later it is. |
SignatureDoesNotMatch | 403 | The request signature is wrong. |
RequestTimeTooSkewed | 403 | The request time is more than 15 minutes from the server's. |
AuthorizationHeaderMalformed | 400 | The signature's credential scope names a region other than the endpoint's. |
NotImplemented | 501 | The request carries a query parameter this operation does not take. |
SlowDown | 503 | Too many requests at once; a retry after the Retry-After interval goes through. |
ServiceUnavailable | 503 | A temporary failure; a retry usually succeeds. |
Differences from Amazon S3
A few things work a little differently on STRG, each listed here with what it means for your requests.
| Aspect | Amazon S3 | STRG |
|---|---|---|
Rule ID | Returned as stored | Not returned: set aside when the rules are saved |
| Case of origins and headers | As sent | Lowercased |
Order of AllowedMethod | As sent | Not guaranteed, so comparing methods as a set is the reliable check |
| Permission | s3:GetBucketCORS, granted per identity | Included in every access key that can reach the bucket |
| Bucket in another region | 301 redirect with x-amz-bucket-region | 404 NoSuchBucket. Each bucket answers on its own regional endpoint. |
x-amz-expected-bucket-owner | Checked against the bucket owner | Welcome, with nothing to check: a key only ever reaches buckets of its own account |
The rules read here are the ones the S3 endpoint applies to browser requests for the bucket: a
preflight they do not allow gets 403 AccessForbidden, and responses to an origin they allow
carry the CORS headers. CORS rules describes what a
browser sees.
Examples
Each example reads the CORS rules of my-bucket, and treats a bucket without rules as an empty
list.
- AWS CLI
- Python (boto3)
- JavaScript (AWS SDK v3)
aws s3api get-bucket-cors \
--bucket my-bucket \
--endpoint-url https://s3.eu-central-1.strg.com \
--region eu-central-1
The CLI prints the rules as JSON, under CORSRules. That list is also the format the dashboard's
CORS editor takes, so it can be pasted straight in. For a bucket without rules, the CLI ends with
An error occurred (NoSuchCORSConfiguration) and a non-zero exit code.
import boto3
from botocore.exceptions import ClientError
s3 = boto3.client(
"s3",
endpoint_url="https://s3.eu-central-1.strg.com",
region_name="eu-central-1",
)
try:
rules = s3.get_bucket_cors(Bucket="my-bucket")["CORSRules"]
except ClientError as error:
if error.response["Error"]["Code"] != "NoSuchCORSConfiguration":
raise
rules = []
for rule in rules:
print(rule["AllowedOrigins"], rule["AllowedMethods"])
import { GetBucketCorsCommand, S3Client } from "@aws-sdk/client-s3";
const client = new S3Client({
endpoint: "https://s3.eu-central-1.strg.com",
region: "eu-central-1",
});
let rules = [];
try {
const output = await client.send(new GetBucketCorsCommand({ Bucket: "my-bucket" }));
rules = output.CORSRules ?? [];
} catch (error) {
if (error.name !== "NoSuchCORSConfiguration") throw error;
}
for (const rule of rules) {
console.log(rule.AllowedOrigins, rule.AllowedMethods);
}