Skip to content

Configure CORS on the bucket

This is the step people skip and then spend an afternoon debugging. Without it, uploads from the browser fail with a CORS error in the browser console, while server-side calls from Salesforce to Google Cloud Storage keep working. So the symptom is “uploads from the UI fail but admin diagnostics pass”, which is easy to misdiagnose.

The same GET rule also powers the photo editor. Large images, over Salesforce’s 4 MB server-side limit, load straight into the canvas from your bucket. Without GET in the CORS rule, or if your Salesforce origin is not listed, large external images open in view-only mode instead of being editable. Editing is capped at 50 MB.

CORS cannot be set in the Google Cloud console. You apply it with the gcloud command line or the JSON API. The gcloud flow below is the easiest.

  1. Install the Google Cloud CLI, one time per machine, from https://cloud.google.com/sdk/docs/install. Then:

    gcloud auth login
    gcloud config set project YOUR-PROJECT-ID
  2. Save the following to cors.json on your machine. Replace the entries in origin with your actual Salesforce org domains, listing every domain users will upload from: production org, sandboxes, and Experience Cloud sites.

    [
      {
        "origin": [
          "https://your-org.lightning.force.com",
          "https://your-org.my.salesforce.com",
          "https://your-org.sandbox.my.salesforce.com",
          "https://your-experience-site.my.site.com"
        ],
        "method": ["GET", "PUT", "HEAD"],
        "responseHeader": ["*", "Content-Type", "ETag", "x-goog-resumable"],
        "maxAgeSeconds": 3000
      }
    ]

    The "*" in responseHeader is required. When File Metadata sync is enabled, Sliick signs x-goog-meta-* headers into the browser upload, and those header names are configurable per org. Google Cloud Storage only lets the browser send request headers the CORS preflight allows, so without the "*" wildcard the upload fails with Failed to fetch or “Could not reach storage” even though the origin is allowed. The wildcard makes it accept whatever headers the signed PUT carries.

  3. Apply it to your bucket:

    gcloud storage buckets update gs://YOUR-BUCKET-NAME --cors-file=cors.json
  4. Verify:

    gcloud storage buckets describe gs://YOUR-BUCKET-NAME --format="default(cors_config)"

Finding your Salesforce domains: in Salesforce Setup → My Domain, the Current My Domain URL and Lightning URL are the two you need for the production org. Sandboxes have their own equivalents. Experience Cloud sites appear in Setup → Digital Experiences → All Sites.

Next: Create the service account and HMAC key.