CORS Debugging Guide
MDN describes CORS as an HTTP-header based mechanism that lets a server indicate which other origins a browser may allow to load resources. Read the browser-level reference at MDN CORS Guide. This Formalint page turns that model into a debugging checklist.
What CORS is really telling you
A CORS error does not always mean the API is down. It often means the browser received a response but refused to expose it to frontend JavaScript. That is why curl, Postman and a backend service may succeed while the browser still fails.
Collect browser evidence first
| Evidence | Where to look | Why it matters |
|---|---|---|
| Console error | Browser DevTools Console | Names the missing or invalid CORS header. |
| OPTIONS request | Network tab | Shows whether preflight reached the server. |
| Origin header | Request headers | Shows the exact scheme, host and port the server must allow. |
| Response headers | Response headers | Confirms whether the API or proxy emitted CORS headers. |
Reproduce preflight safely
curl -i -X OPTIONS https://api.example.com/resource \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: content-type,authorization"Header rules that prevent most mistakes
- Use a specific origin when credentials such as cookies or HTTP auth are involved.
- Do not combine
Access-Control-Allow-Origin: *with credentialed browser requests. - Include
Vary: Originwhen a gateway dynamically returns different allowed origins. - Allow the headers the browser asks for in
Access-Control-Request-Headers. - Handle
OPTIONSat the same layer that protects the real API route.
Common CORS failures
| Browser message | Likely cause | Next check |
|---|---|---|
| Allow-Origin missing | API or proxy did not attach the CORS header. | Check route config, gateway rules and Nginx response headers. |
| Preflight failed | OPTIONS route blocked by auth, WAF, proxy or app router. | Run the curl OPTIONS command and inspect status. |
| Credentials not supported | Cookie request lacks explicit origin or credentials header. | Check frontend credentials setting and server headers. |
| Header not allowed | Custom header not listed in Access-Control-Allow-Headers. | Compare requested headers with allowed headers. |
Server-side checklist
origin observed:
method:
request headers:
preflight status:
allow-origin returned:
allow-methods returned:
allow-headers returned:
allow-credentials returned:
vary origin present:
gateway or app layer responsible:Treat CORS as a browser access-control decision. Debug the network response first, then decide whether the fix belongs in the API app, Nginx, CDN, gateway or frontend request options.
Related: curl API Debugging Cheatsheet, HTTP Headers Reference, Nginx Reverse Proxy Checklist, API Debugging Handbook.