CORS Handbook
The complete guide to understanding and fixing CORS errors.
Built by headertest.com
CORS gets weird fast when you move from app code into infrastructure. In Pulumi, that usually means you’re not “fixing a header bug” — you’re wiring behavior across buckets, CDNs, API gateways, Lambda responses, and sometimes the browser cache too. I’ve seen teams burn hours changing app code when the real problem was an S3 bucket CORS rule, an API Gateway preflight route, or CloudFront stripping Origin from the cache key. ...
CORS on AWS ECS Fargate usually goes wrong for one boring reason: people configure it in the wrong layer. I’ve seen teams add CORS headers in app code, then put an ALB, CloudFront, Nginx, or API Gateway in front of it and accidentally strip or duplicate headers. Then the browser says “CORS failed” and everybody starts guessing. Here’s the practical way to think about it: Browser enforces CORS Your backend must return the right headers Every proxy in front of your app must preserve them Preflight OPTIONS requests must succeed You cannot “fix CORS” from frontend code If your app runs on ECS Fargate, CORS is not an ECS feature. ECS just runs containers. The actual CORS behavior comes from whatever is serving traffic: ...
Custom schemes are where a lot of clean CORS theory goes to die. On the web, most teams think in terms of https://app.example.com calling https://api.example.com. Then product ships a desktop app, a mobile WebView, or an Electron wrapper, and suddenly requests come from stuff like: myapp://local capacitor://localhost ionic://localhost tauri://localhost file:// null That’s when the usual “just set Access-Control-Allow-Origin” advice stops being enough. I’ve seen this play out on a desktop app rollout where the API worked perfectly in browsers, then failed in production for the packaged app. Same frontend code, same backend, same auth flow. The only difference was the request origin. ...
If you’ve ever opened an HTML file directly in the browser and watched fetch() explode with a CORS error, you’ve hit one of the weirdest corners of web security: file://. I’ve seen this trip up experienced developers, not just beginners. The usual reaction is: “But I’m not even cross-origin. It’s just a local file.” The browser disagrees. The core problem with file:// A page loaded from file:///Users/me/demo/index.html does not behave like a normal web app served from http://localhost. Browsers treat file:// as a special origin, and in many cases as an opaque origin or at least something heavily restricted. That means requests from a local file to: ...
CORS on AWS API Gateway HTTP APIs looks simple right up until your browser starts throwing No 'Access-Control-Allow-Origin' header and your backend logs show everything is “working fine.” I’ve hit this enough times that I now treat CORS as part browser contract, part API Gateway feature, and part trap. This guide is about API Gateway HTTP APIs specifically, not the older REST API product. The behavior is different enough that mixing them up causes bad advice and wasted hours. ...
Browsers used to treat “public website calls my router or local dev box” as mostly a weird edge case. That changed. Private Network Access, or PNA, adds another browser-enforced check when a page on a less-private network tries to reach a more-private one. If you build APIs, admin panels, local device UIs, or anything that runs on localhost, your CORS setup now has a second layer to think about. The short version: ...
CORS on API Gateway looks easy until the browser starts throwing vague errors and Terraform happily deploys a broken setup. I’ve hit this enough times that I now treat CORS as a first-class part of the API contract, not a checkbox. If you manage AWS API Gateway with Terraform, the main thing to remember is this: CORS is enforced by browsers, but you implement it in API Gateway and your backend responses. ...
If you’re trying to call the Webflow CMS API from browser JavaScript, CORS is usually the first wall you hit. The short version: Webflow CMS API requests from the browser are a bad fit unless Webflow explicitly allows your origin. Even when the API works fine in Postman or curl, the browser enforces CORS and blocks the response before your code can touch it. This guide is the practical version: what CORS means for Webflow CMS, what will fail, what can work, and what to copy-paste. ...
CORS in .NET Core and classic ASP.NET solve the same browser problem, but they feel very different once you actually ship APIs with them. If you’ve worked on both stacks, you’ve probably noticed the split right away: ASP.NET Core gives you a clean, policy-based CORS system built into the middleware pipeline. Classic ASP.NET usually feels more fragmented. Depending on whether you’re in Web API, MVC, IIS, or some mix of all three, CORS can be straightforward or weirdly annoying. That difference matters because CORS bugs are rarely “the browser is wrong.” Usually the server emitted the wrong headers, emitted them in the wrong order, or skipped them on preflight requests. ...
tRPC is great right up until your frontend and API live on different origins and the browser starts throwing CORS errors that look unrelated to your code. I’ve seen this happen a lot with tRPC because the transport feels “magic” when everything is same-origin. Then you split your app across app.example.com and api.example.com, or you run Vite on localhost:5173 against a backend on localhost:3000, and suddenly every request is blocked before your resolver runs. ...