CORS Handbook
The complete guide to understanding and fixing CORS errors.
Built by headertest.com
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. ...
Mailgun webhooks and CORS get mixed up all the time, mostly because they solve different problems. Here’s the blunt version: Mailgun sending a webhook to your server does not need CORS Your browser calling your webhook endpoint does need CORS Your frontend should usually not call Mailgun directly That’s the whole mental model. If you keep those three rules straight, most confusion disappears. The short answer If Mailgun sends an event like delivered, opened, or failed to your backend: ...
I’ve seen the same CORS mess play out on Hetzner boxes more than once: the app works locally, staging kind of works, then production starts throwing browser errors that look random until you realize the reverse proxy, the API, and the frontend all disagree about who is allowed to talk to whom. This case study comes from a very normal setup on Hetzner Cloud: frontend on app.example.com API on api.example.com Nginx on the VPS as reverse proxy Node.js API behind it TLS terminated at Nginx a second environment for previews on *.staging.example.com The team had deployed cleanly. DNS was right. Certificates were fine. Curl looked fine. The browser was not fine. ...
Google Cloud Endpoints makes CORS feel simpler than it really is. That’s both the nice part and the dangerous part. If you’re running Endpoints with ESP or ESPv2, you’ve got a few ways to handle CORS: let Endpoints proxy and pass CORS through from your backend make Endpoints handle CORS preflight for you split responsibility between proxy and backend All three work. Not all three age well. I’ve seen teams “fix CORS” by slapping Access-Control-Allow-Origin: * onto everything, then later wonder why authenticated browser requests still fail. CORS is one of those areas where the browser is very literal, and Google Cloud Endpoints doesn’t save you from bad policy choices. ...
Webhook signature verification and CORS get mixed up all the time, usually in bad ways. The short version: webhook verification with HMAC should almost always happen server-side, and CORS is only relevant if a browser is calling your verification endpoint. A webhook provider like GitHub, Stripe, or Slack is not a browser. It does not care about Access-Control-Allow-Origin. That distinction saves a lot of confusion. The mental model There are really two separate flows: ...
CORS in Microsoft Edge extensions trips people up because extensions are not normal web pages, but they’re also not completely exempt from browser security rules. I’ve seen teams waste hours debugging a “CORS issue” that was actually a host permission problem, a content script limitation, or a server sending the wrong headers. If you build Edge extensions, you need to separate three execution contexts in your head: Content scripts Extension pages like popup, options, side panel Background/service worker That distinction explains most CORS bugs. ...
Webhook security and CORS get mixed together all the time, and that usually leads to one of two bad outcomes: people add CORS headers to webhook endpoints that never needed them people assume CORS protects webhook endpoints from abuse It does neither. Here’s the blunt version: CORS is a browser policy, not an authentication system, not an origin firewall, and definitely not webhook verification. If your payment provider, GitHub app, or internal service is sending server-to-server webhooks, CORS is usually irrelevant. ...