CORS not being passed to Cloudflare from Nginx

I have the following Nginx settings on my server:

location / {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Max-Age 3600;
    add_header Access-Control-Expose-Headers Content-Length;
    add_header Access-Control-Allow-Headers Range;
}

It works fine by allowing CORS. However, when I try to switch CloudFlare’s CDN on, it s giving me CORS errors:

Access to script at ‘https://.com’ from origin 'https://.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

What am I missing here? Shouldn’t Cloudflare automatically pass the CORS headers from my server to the browser?

Unless you are modifying them in a Worker, they will be passed through.

What is the output of the following command:

curl --dump-header - -o /dev/null https://yourdomain.com -H "Origin: https://youroriginrequestheader.com"

If you see the correct headers in the output, then the issue is not Cloudflare related. The wildcard CORS header does not work in all cases, so you might need to investigate there.

If you do not see the correct headers in the output, the please run the following command, and share the output, which will show the output from your Origin server, and should confirm that you are sending the headers to Cloudflare in the first place:

curl --dump-header - -o /dev/null https://yourdomain.com -H "Origin: https://youroriginrequestheader.com" --resolve yourdomain.com:443:<your origin IP address>

Thanks for your reply @michael.

I executed both commands.

The first command did not return any Access-Control headers, just the following:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0HTTP/1.1 301 Moved Permanently
Date: Sun, 14 Feb 2021 20:05:01 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=dfd7f6332215b566bfa4d2aea64fcf7e71613333101; expires=Tue, 16-Mar-21 20:05:01 GMT; path=/; domain=.***.com; HttpOnly; SameSite=Lax; Secure
Location: https://***.com
Cache-Control: max-age=14400
CF-Cache-Status: MISS
cf-request-id: 0843be92dd0000374a9d973000000001
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Report-To: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=W%2FMHqMZKQshgMRXKAsPJ2eSWkE3rLew0%2BOhTo%2FIPdw5WudUHgaI%2Bn3UZltSh8Divl7Mook6t5jFmbtCvoKQZJGY99VkdPRcuyKN9jGX%2BYMzij2Kq"}],"max_age":604800,"group":"cf-nel"}
NEL: {"max_age":604800,"report_to":"cf-nel"}
Server: cloudflare
CF-RAY: 621966cafcd1374a-MXP

So I ran the 2nd command, which returned this:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0HTTP/1.1 404 Not Found
Date: Sun, 14 Feb 2021 20:12:23 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Sorting-Hat-PodId: -1
Vary: Accept-Encoding
X-Frame-Options: DENY
Vary: Accept
X-Shopify-Stage: production
Content-Security-Policy: block-all-mixed-content; frame-ancestors 'none'; upgrade-insecure-requests; report-uri /csp-report?source%5Baction%5D=not_found&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=storefront_section%2Fshop&source%5Bsection%5D=storefront&source%5Buuid%5D=28ab2abc-abea-4e60-a017-2d6953c61407
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 1; mode=block; report=/xss-report?source%5Baction%5D=not_found&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=storefront_section%2Fshop&source%5Bsection%5D=storefront&source%5Buuid%5D=28ab2abc-abea-4e60-a017-2d6953c61407
X-Dc: gcp-us-central1,gcp-us-east1,gcp-us-east1
X-Request-ID: 28ab2abc-abea-4e60-a017-2d6953c61407
Set-Cookie: _y=5a3e8338-9d1e-4f8f-abc8-aac0eb53f160; Expires=Mon, 14-Feb-22 20:12:23 GMT; Domain=***.com; Path=/; SameSite=Lax
set-cookie: _s=35e61d77-708f-450f-90a3-89a2975b0c13; Expires=Sun, 14-Feb-21 20:42:23 GMT; Domain=***.com; Path=/; SameSite=Lax
set-cookie: _shopify_y=5a3e8338-9d1e-4f8f-abc8-aac0eb53f160; Expires=Mon, 14-Feb-22 20:12:23 GMT; Domain=***.com; Path=/; SameSite=Lax
set-cookie: _shopify_s=35e61d77-708f-450f-90a3-89a2975b0c13; Expires=Sun, 14-Feb-21 20:42:23 GMT; Domain=***.com; Path=/; SameSite=Lax
set-cookie: _shopify_fs=2021-02-14T20%3A12%3A23Z; Expires=Mon, 14-Feb-22 20:12:23 GMT; Domain=***.com; Path=/; SameSite=Lax
CF-Cache-Status: DYNAMIC
cf-request-id: 0843c551340000405809b9c000000001
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 621971951e9e4058-LHR
alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400

As you might see the origin server is Shopify’s server. Not sure if that makes any difference, however, it does work perfectly when I do not use Cloudflare’s CDN.

The first one returned a 301, and CORS and redirects normally result in :exploding_head:.

The second one is a 404, with no Access-Control-Allow-Origin response at all.

But if the Origin is Shopify, where are you putting the Nginx config?

Also, Shopify is a Cloudflare customer, so there are particular requirements and limitations on using your own Cloudflare account in front of Shopify. Check the support article here.

Well, I may have misunderstood which one is the origin. What I’m basically doing is, I’d like to display assets on my Shopify site from my Nginx server utilizing Cloudflare to cache + compress my assets on my server and serve content via the CDN.

The command I used for the 1st one is:

curl --dump-header - -o /dev/null https://nginxdomain.com/asset.js -H "Origin: https://shopifydomain.com"

…and for the second command:

curl --dump-header - -o /dev/null https://nginxdomain.com/asset.js -H "Origin: https://shopifydomain.com" --resolve nginxdomain.com:443:shopify_domain_IP

Am I supposed to be doing it the other way around?

Shopify is outside my sphere of knowledge. There is a separate Shopify Community which might be a better place to get help about their platform.

The first command I gave replicates the request for the “requested resource” you referred to in your first post. In your browsers F12/Dev Tools there is normally an option to “Copy as cURL”. The version I gave is a bit simplified, as most of what your browser is doing will not be relevant.

The second command just takes your Cloudflare account out of the equation. The IP address should be the Origin IP of nginxdomain.com.

Actually, I have just checked and I get the same problem while trying to access the resources locally. So it’s not a shopify issue, that’s for sure.

I checked again, that if I enable the “cloud icon” on Cloudflare it stops passing the CORS headers from my server, but when I disable it, my server does pass the correct headers.

What could be the issue here?