Getting strange Access-Control-Allowed-Origin headers

Hi, we deployed a SvelteKit site to Netlify and with one of the latest releases of SvelteKit, the CORS is also checked when doing SSR (see simulate CORS errors in server-side fetch by Rich-Harris 路 Pull Request #6550 路 sveltejs/kit 路 GitHub)

Since the site started to generate these CORS errors, I did some debugging and noticed that the Dato CMS GraphQL API returns http://localhost:5173 as Access-Control-Allowed-Origin on a totally different domain. This is the URL I was previously using for local developing.

The issue doesn鈥檛 arise when the Browser performs the requests, it鈥檚 strictly happening in a Server-to-Server context. So I was wondering why this is? Could it be, that DatoCMS caches an origin for a given API Key? Could it be that the Origin header is missing in the request and DatoCMS is using a cached value for the response?

Why is DatoCMS not responding with Access-Control-Allowed-Origin: * ?

Quick update: I can confirm that the request does not have an Origin header value set when doing Server-to-Server communication. So the question/problem boils down to:

If the graphql request does not have an Origin set, the response from DatoCMS might contain an invalid Access-Control-Allowed-Origin value. Ideally, the value would be * in these cases鈥

Update: This is a bug in SvelteKit (Add `Origin` request header for the server-side fetch 路 Issue #6608 路 sveltejs/kit 路 GitHub), since the Origin header should be set for these requests. Maybe it鈥檚 still worth investigating by your engineers what should happen if the Origin is missing?

Hello @tools1 and welcome to the community,

I鈥檒l check with the development team on how we deal with empty Origin headers and i鈥檒l get back to you.

Thank you for letting us know!

Request without Origin:

curl '' -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -H 'Authorization: Bearer XXX' --data-raw '{"query":"{ blogPost{ title } }"}' -v


< HTTP/2 200
< date: Fri, 16 Sep 2022 15:38:31 GMT
< content-type: application/json; charset=utf-8
< access-control-allow-origin: *
< access-control-allow-credentials: true
< access-control-allow-headers: authorization, content-type, x-environment, x-site-domain, x-api-version, user-agent, x-session-id, x-include-drafts, x-exclude-invalid
< access-control-allow-methods: GET, POST, PUT, OPTIONS, DELETE
< access-control-expose-headers: x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset
< access-control-max-age: 1728000
< vary: Authorization, Accept-Encoding, X-Environment, X-Include-Drafts, X-Exclude-Invalid, Origin

So with no Origin, we respond with *.

The header access-control-allow-origin: http://localhost:5173 can only be returned when the request contains an origin: http://localhost:5173 header :confused:

Also note that the vary header contains origin, so requests with different origins are treated differently, and do not use the same cache.

Thanks for your replies. I鈥檓 still not sure how the localhost origin appeared on the deployed website鈥 could it be related to caching?

Either way, the issue in SvelteKit is now fixed and should send a proper Origin header with each request.