GuidesDIAGNOSE
Fix an axios CORS error (Network Error)
In the browser, axios reports a CORS failure as AxiosError: Network Error with code ERR_NETWORK and no error.response because the browser blocked the response before axios could read it. Headers set on the axios request cannot fix it: the API has to send Access-Control-Allow-Origin, or you call it through your own backend or a dev-server proxy. For public third-party APIs, set baseURL to https://proxy.cors.dev/ followed by the API's origin.
Recognize a CORS failure in axios
In browsers axios sends requests with XMLHttpRequest: its default adapter list is ['xhr', 'http', 'fetch'], and http is the Node.js adapter. When CORS blocks the response, the request fails without an HTTP response, and axios rejects with the message Network Error, code set to ERR_NETWORK and error.response set to undefined. We checked this with axios 1.20.0 in Chromium. axios cannot tell a CORS block from being offline or a DNS failure; the browser console names the cause, for example Access to XMLHttpRequest at 'https://api.deezer.com/artist/27' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
| Property | Value |
|---|---|
| error.name | AxiosError |
| error.message | Network Error |
| error.code | ERR_NETWORK |
| error.response | undefined |
import axios from 'axios';
try {
const { data } = await axios.get('https://api.deezer.com/artist/27');
console.log(data.name);
} catch (error) {
if (axios.isAxiosError(error) && error.code === 'ERR_NETWORK' && !error.response) {
// CORS, offline or DNS: the browser console names the exact cause
console.error('Request blocked before a response reached axios', error.message);
}
}Why request headers do not fix it
Access-Control-Allow-Origin and the other Access-Control-Allow-* headers are response headers that the API sends. Putting them in the axios headers option does not give your page access. Any request header outside the CORS-safelisted set, such as Authorization, X-Api-Key or those Access-Control-Allow-* names, makes the browser send an OPTIONS preflight first, and the API must list that header in Access-Control-Allow-Headers.
axios sends a plain object body as JSON with Content-Type: application/json, which also needs a preflight. withCredentials: true requires Access-Control-Allow-Credentials: true and the exact origin in Access-Control-Allow-Origin, not *. Check what the API answers to the preflight with the curl command below: look for a 2xx status and the Access-Control-Allow-* headers; details in CORS preflight failed.
curl -si -X OPTIONS https://api.example.com/items \
-H 'Origin: http://localhost:5173' \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: content-type'Pick the fix
| Situation | Fix | Works in production |
|---|---|---|
| Your own API | Allow your frontend's origin and answer OPTIONS preflights | Yes |
| Your API during development | Relative baseURL and a dev-server proxy | No, dev server only |
| Public API without CORS headers | baseURL through https://proxy.cors.dev/ | Yes, GET and HEAD on the free tier |
| Third-party API that needs a key | Call it from your own backend | Yes, the key stays server-side |
| Node.js script or server | Nothing: CORS does not apply | Not applicable |
Fix it on your API
If you run the API, allow your frontend's origin and answer OPTIONS preflights. Framework guides: Express, Fastify, Hono, FastAPI, Django, Laravel, Spring Boot.
Use a dev-server proxy
Point axios at a relative baseURL such as /api and let the dev server forward /api to the API: Vite has server.proxy, the Angular CLI has proxyConfig. The browser then sees a single origin. This only works while the dev server runs: CORS error on localhost, Vite integration.
Third-party APIs without CORS headers
For a public API you do not control that sends no CORS headers, create an axios instance whose baseURL is https://proxy.cors.dev/ followed by the API's origin. Relative paths such as /artist/27 are appended to it. api.deezer.com sends no CORS headers; through the proxy the same GET request works. axios's default Accept header passes through; Authorization and custom headers are rejected on the free tier.
import axios from 'axios';
const deezer = axios.create({
baseURL: 'https://proxy.cors.dev/https://api.deezer.com',
});
const { data: artist } = await deezer.get('/artist/27');
console.log(artist.name, artist.nb_fan);axios in Node.js
CORS is a browser rule. axios in Node.js uses the http adapter and never runs into CORS, which is why the same call works in a Node.js script, Postman or curl: Postman vs the browser. Server code in frameworks such as Next.js can call the API directly: Next.js integration.
Good questions.
Why does axios say Network Error instead of a CORS error?
The browser hides the reason for a CORS block from JavaScript. axios only sees a failed request without a response, so it reports Network Error with ERR_NETWORK. The browser console shows the real CORS message.
Can I fix an axios CORS error by adding headers?
No: Access-Control-Allow-* headers are response headers that the API must send. Extra request headers only add a preflight.
Does withCredentials fix CORS in axios?
No: it sends cookies, and it makes the rules stricter. The API must answer with Access-Control-Allow-Credentials: true and the exact origin instead of *.
Why does the request work in Postman but fail with axios?
Postman is not a browser and does not enforce CORS. The browser does, so the API's response needs the CORS headers for your origin.
Can I send an axios POST through a CORS proxy?
Not on the cors.dev free tier: a POST returns HTTP 405 with X-Cors-Error: method_not_allowed. Managed access on Pro supports POST, PUT, PATCH and DELETE on hosts you enable: pricing.