Capture one error and its context
Record frontend origin, final API URL, method, time, authentication state and Fetch credentials mode. A different port or HTTP/HTTPS difference may already matter. Also note headers explicitly set by the application, particularly Content-Type, Authorization or custom CSRF headers.
Examine a specific operation instead of mixing similar console messages. On retry, preflight may be served from the browser cache. ‘I see no OPTIONS’ therefore does not automatically mean this request type needs no preflight.
Share only sanitised diagnostic evidence. Cookies, bearer tokens and sensitive payloads do not belong in unprotected screenshots or HAR exports. Header names, harmless values, status and a non-secret correlation identifier usually suffice for diagnosis.
Step 1: was an HTTP response received?
Not every failed browser fetch is a CORS configuration error. Check DNS, TLS, connection errors and whether an HTTPS page is trying to reach a disallowed HTTP resource. The frontend's Content Security Policy may also prevent a request. The MDN CORS error overview helps interpret the browser message.
If the browser cannot obtain an appropriate HTTP response, adding Access-Control-Allow-Origin does not fix that connection problem. See the foundations in TLS certificates and CSP. In the affected environment, check whether the expected service responds or an upstream error page appears.
Step 2: is preflight failing?
Preflight is an OPTIONS request with Origin and Access-Control-Request-Method, optionally supplemented by Access-Control-Request-Headers. It announces the method and header names; it is not yet the authenticated business request. The Fetch specification requires appropriate permission before the browser continues with that request.
Check these cases:
On narrow screens, scroll the table sideways.
| Network-panel observation | Likely point to check |
|---|---|
| OPTIONS receives 401 or a login page | The authentication layer requires credentials for preflight; handle CORS before business authentication |
| OPTIONS receives 404 or 405 | Routing, proxy or application does not handle preflight appropriately |
| OPTIONS receives 2xx but the browser still refuses | Origin, requested method or headers do not match the response permission |
Message names Authorization | Allow this header explicitly; a header wildcard is insufficient |
| OPTIONS is redirected | Investigate target URL, HTTPS redirect, slash normalisation or login redirect |
A 204 alone is not successful CORS permission. Read the headers of that same response. Nor should you assume permission for a neighbouring route applies to the path actually requested.
For redirects, a direct request to the intended API URL is usually easier to control. Browser and flow differences make redirect chains another source of errors. Correct the responsible routing or preflight path rather than removing authentication protection.
Step 3: read the actual response separately
If preflight succeeded, locate the subsequent API request. A header only on OPTIONS is insufficient. The API might then return 401, 403 or 500, and that error path may lack CORS headers. JavaScript then sees a network error even though the actual server error would be crucial to diagnosis.
Allowed frontends should be able to read intended error responses. This does not mean exposing internal stack traces. Check the error contract and origin permission together on success and error paths.
An actually received 401 response with correct CORS permission is, in turn, an authentication problem, not a CORS problem. Distinguish HTTP status from a Fetch exception in the client. CORS may make a rejected business response readable; it does not thereby permit the rejected operation.
Step 4: compare the origin and duplicate headers
Compare Origin and Access-Control-Allow-Origin, including scheme and port. The allowed origin contains no path or trailing slash. Multiple origins in a comma-separated list or two conflicting header lines are not a valid fix.
It is particularly useful to check which layer sets headers: application, reverse proxy, gateway or CDN. If the application returns the correct origin and the proxy appends *, the response reaching the browser is decisive. The MDN reference for mismatched origins also identifies multiple permission headers as a cause.
Change the responsible layer and test the entire path again. A local response directly from the backend may be correct while the delivered proxy response remains wrong. Dynamic origin permission also requires considering Vary: Origin in caching.
Step 5: separate credentials from cookie conditions
With credentials: "include", a readable cross-origin response needs a specific matching origin and Access-Control-Allow-Credentials: true. A literal * is insufficient in this mode. Check the client setting, not just whether a cookie happened to appear in a capture.
Even with correct CORS permission, the required cookie may be missing. Check domain, path, Secure, SameSite, expiry and the browser's cookie notices. Third-party cookie rules may further restrict access. SameSite=None; Secure does not guarantee every browser sends every cookie in every context. The MDN CORS documentation separates these layers.
A deliberately set Authorization header needs its own preflight permission. Do not randomly change credentials mode to make an error disappear. The choice must fit the intended cookie or token model.
Three changes that only hide the error
mode: "no-cors" does not make a protected API response normally readable. The response may remain opaque to JavaScript; status, headers and content are then unavailable as they would be in a normal CORS response. This is no solution for a JSON client.
Setting Access-Control-Allow-Origin as your own request header grants no permission either. The server makes that decision in the response. An extra unusual request header may even alter the flow further.
Finally, a browser extension or disabled web security creates an environment different from your users'. Do not use it as acceptance evidence. CORS for APIs describes the intended configuration.
Demonstrate success and limit changes
After correction, repeat the same operation with the same origin and client configuration. Add an origin you control that is not allowed, plus signed-out and business-rejected cases. Document whether preflight, actual response and JavaScript reading each produce the expected result. Server permissions must continue to apply independently.
Where possible, change one responsible rule per diagnostic hypothesis and preserve the previous configuration. If side effects occur, revert that specific change; do not expand every origin, method and header as a precaution. Account for cached preflight permissions when retesting.
The public API Security Check can show response headers as an additional snapshot. It reproduces neither your cookies nor the specific browser error. The appropriate fix therefore follows the observed flow. Sources checked: 27 September 2026.
Sources and date
Sources checked: 27 September 2026. Links also appear alongside the statements they support.