Skip to content

Fix: Axios Network Error — Request Failed with Status Code 0

FixDevs · (Updated: )

Part of:  React & Frontend Errors

Quick Answer

How to fix Axios 'Network Error' with no status code — CORS blocks, SSL certificate issues, request timeout, no internet connection, and debugging with interceptors.

The Error

An Axios request fails with a generic network error and no HTTP status code:

axios.get('https://api.example.com/data')
  .catch(error => {
    console.log(error.message);     // "Network Error"
    console.log(error.response);    // undefined — no response received
    console.log(error.code);        // "ERR_NETWORK" or undefined
  });

Or:

AxiosError: Network Error
    at XMLHttpRequest.handleError (axios/lib/adapters/xhr.js:...)

Or a timeout error:

AxiosError: timeout of 5000ms exceeded
    code: 'ECONNABORTED'
    message: 'timeout of 5000ms exceeded'

The request never reaches the server — or the server returns a response that the browser refuses to pass to JavaScript.

Why This Happens

An Axios “Network Error” with no error.response means the HTTP request didn’t complete successfully at the network level. The browser didn’t receive a readable response. Unlike an HTTP 500 or 404, this error never reaches your application code with a parseable response object — Axios constructs an AxiosError with message: "Network Error" and error.response === undefined. That alone tells you the failure happened before any HTTP semantics were established.

The category of failure splits along browser-versus-Node lines. In the browser, the XHR or fetch adapter is at the mercy of the platform: CORS, mixed content, certificate validation, and extension-level blocking all surface as the same opaque “Network Error” string because the browser deliberately hides details for security. In Node.js, Axios returns the raw socket error code (ECONNREFUSED, ENOTFOUND, ETIMEDOUT, CERT_HAS_EXPIRED), which makes diagnosis dramatically easier. If you can reproduce a “Network Error” in Node, you almost always get a useful error code; if it’s browser-only, suspect CORS or mixed content first.

Common root causes, ordered by frequency in real-world apps:

  • CORS block — the browser made the request, the server responded, but the response was blocked because CORS headers were missing or wrong. The browser hides the actual response from JavaScript for security, resulting in “Network Error”.
  • Request timeout — the server took longer than timeout milliseconds to respond. Axios aborts the request.
  • No internet / DNS failure — the device has no connectivity, or the domain doesn’t resolve.
  • SSL/TLS certificate error — the server’s certificate is invalid, expired, or self-signed. The browser blocks the connection.
  • Mixed content — your HTTPS page makes an HTTP request. Browsers block this.
  • Server completely unreachable — the server is down, the port is closed, or a firewall is blocking the connection.
  • Ad blocker or browser extension — some extensions block requests to analytics, tracking, or ad domains.
  • AbortController fired — a stale React effect or query cancellation aborts the request mid-flight, producing error.code === 'ERR_CANCELED' (which still falls under “no response received”).

Version History That Changes the Failure Mode

Axios has been around since 2014, but the failure surface changed materially with the 1.0 release on October 4, 2022. Before 1.0, Axios was effectively frozen on the 0.27.x line for years and bundled XHR-only adapters with no AbortController support. After 1.0, the library gained native ESM exports, dropped its bundled form-data dependency, and rewrote the adapter loader. If you upgraded from 0.27.x to 1.x without changing your code, you may be hitting failures that did not exist before — particularly around request cancellation and FormData handling.

Concrete version landmarks worth knowing:

  • Axios 0.21.1 (Dec 2020) patched a CVE around proxy handling. Anything still on 0.21.0 or older has known vulnerabilities and should be upgraded before debugging.
  • Axios 0.27.0 (Apr 2022) dropped support for URLSearchParams polyfills and shifted FormData behavior. Multipart uploads that worked on 0.26 sometimes break here with no error message — they just produce empty network requests.
  • Axios 1.0.0 (Oct 4, 2022) is the major rewrite. It added official AbortController support (signal option), introduced first-class ESM, and changed the default behavior of transformResponse. Code that relied on CancelToken still works but is deprecated.
  • Axios 1.4 (May 2023) fixed several “Network Error” false positives that occurred when responses had unusual Content-Type headers.
  • Axios 1.6 (Nov 2023) added the fetch adapter as an alternative to XHR, which behaves differently for streaming responses and CORS edge cases.
  • Axios 1.7+ (2024) continued to harden the fetch adapter. If you see “Network Error” only on certain browsers, switching adapters via adapter: 'fetch' or adapter: 'xhr' sometimes isolates the cause.

The wider ecosystem is also moving. Node 18 LTS (Apr 2022) shipped a stable native fetch API, Node 21 (Oct 2023) stabilized it further, and node-fetch v3 is now ESM-only — meaning many older Axios alternatives no longer drop in cleanly. If you are on Node 18+ and using Axios only for simple GET/POST, the native fetch may be enough. But Axios still wins on interceptors, automatic JSON parsing, and timeout handling, which is why most production codebases stay with it. There is no public Axios 2.0 roadmap as of mid-2026, so the 1.x line will continue to receive maintenance.

Fix 1: Diagnose with the Browser Network Tab

The most important first step: open DevTools (F12) → Network tab → find the failed request.

CORS block shows:

  • Status: CORS error (in Firefox) or (failed) in Chrome
  • In Console: Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy

Timeout shows:

  • Request hangs for the timeout duration, then fails
  • error.code === 'ECONNABORTED'

SSL error shows:

  • Connection blocked before any HTTP headers are exchanged
  • Console: net::ERR_CERT_AUTHORITY_INVALID or ERR_CERT_DATE_INVALID

No server shows:

  • net::ERR_CONNECTION_REFUSED or net::ERR_NAME_NOT_RESOLVED

Each failure mode requires a different fix.

Fix 2: Fix CORS

CORS blocks are the most common cause of Axios “Network Error”. The request reaches the server but the browser rejects the response. Fix it on the server side by adding the correct CORS headers:

Express.js:

const cors = require('cors');

app.use(cors({
  origin: 'https://app.example.com',  // Allow your frontend origin
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
}));

Or use a proxy in development — route requests through the same origin to avoid CORS entirely:

// vite.config.ts — proxy /api to the backend
export default {
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
      },
    },
  },
};
// Axios call — same-origin, no CORS
axios.get('/api/users');  // Proxied to http://localhost:8080/api/users

For Next.js, use API routes or rewrites() in next.config.js to proxy requests server-side.

Important: CORS is enforced by the browser. Testing with curl or Postman won’t show CORS errors — only browser requests are affected. Always use the browser’s Network tab to diagnose.

Fix 3: Fix Timeout Errors

If error.code === 'ECONNABORTED', the request timed out. The default timeout in Axios is 0 (no timeout). If you set a timeout, increase it or fix the slow server:

// Check your axios instance configuration
const api = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,  // 5 seconds — increase if your server is legitimately slow
});

// Or set per-request
axios.get('/data', { timeout: 30000 });  // 30 seconds for a slow endpoint

Handle timeouts explicitly:

axios.get('/api/report', { timeout: 60000 })
  .catch(error => {
    if (error.code === 'ECONNABORTED') {
      console.error('Request timed out — server may be overloaded');
      // Show user-friendly message, offer retry
    } else {
      throw error;
    }
  });

Implement retry with exponential backoff:

import axios from 'axios';
import axiosRetry from 'axios-retry';

axiosRetry(axios, {
  retries: 3,
  retryDelay: axiosRetry.exponentialDelay,  // 1s, 2s, 4s
  retryCondition: (error) =>
    axiosRetry.isNetworkOrIdempotentRequestError(error) ||
    error.code === 'ECONNABORTED',
});

Fix 4: Fix SSL Certificate Errors

If the server has an invalid, expired, or self-signed certificate, the browser blocks the connection before any HTTP response is received:

In development with a self-signed cert — configure Axios to accept it (Node.js only, never in browser):

const https = require('https');

const api = axios.create({
  httpsAgent: new https.Agent({
    rejectUnauthorized: false,  // Accept self-signed certs
    // WARNING: Only use this in development/testing
  }),
});

In production — fix the actual certificate:

# Check certificate expiry
openssl s_client -connect api.example.com:443 2>/dev/null | openssl x509 -noout -dates

# Renew with Certbot
certbot renew --force-renewal

Mixed content — your HTTPS page calls an HTTP endpoint. Fix by ensuring the API also uses HTTPS, or prefix-relative URLs:

// Broken — HTTP request from HTTPS page
axios.get('http://api.example.com/data');  // Blocked as mixed content

// Fixed
axios.get('https://api.example.com/data');

// Or use protocol-relative (inherits page protocol)
axios.get('//api.example.com/data');  // Uses https:// on HTTPS pages

Fix 5: Add Global Error Handling with Interceptors

Use Axios interceptors to catch and categorize network errors across your entire application:

import axios from 'axios';

const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  timeout: 10000,
});

// Request interceptor — add auth headers
api.interceptors.request.use(
  config => {
    const token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => Promise.reject(error)
);

// Response interceptor — handle errors centrally
api.interceptors.response.use(
  response => response,
  error => {
    if (!error.response) {
      // Network error — no response received
      if (error.code === 'ECONNABORTED') {
        console.error('Request timed out');
        return Promise.reject(new Error('Request timed out. Please try again.'));
      }
      if (!navigator.onLine) {
        console.error('No internet connection');
        return Promise.reject(new Error('No internet connection.'));
      }
      // CORS, SSL, or server unreachable
      console.error('Network error:', error.message);
      return Promise.reject(new Error('Unable to reach the server. Please try again.'));
    }

    // HTTP error responses
    const { status } = error.response;
    if (status === 401) {
      // Token expired — redirect to login
      localStorage.removeItem('token');
      window.location.href = '/login';
    } else if (status === 429) {
      return Promise.reject(new Error('Too many requests. Please wait a moment.'));
    }

    return Promise.reject(error);
  }
);

export default api;

Fix 6: Check Connectivity Before Requests

For better UX, detect connectivity issues before making requests:

async function fetchWithConnectivityCheck(url, options = {}) {
  if (!navigator.onLine) {
    throw new Error('No internet connection');
  }

  try {
    return await axios.get(url, options);
  } catch (error) {
    if (error.code === 'ERR_NETWORK') {
      // Could be CORS, SSL, or server down — check the console
      throw new Error('Network request failed. Check the browser console for details.');
    }
    throw error;
  }
}

Listen for online/offline events:

window.addEventListener('online', () => {
  console.log('Connection restored');
  // Retry pending requests
});

window.addEventListener('offline', () => {
  console.log('Connection lost');
  // Show offline indicator in UI
});

Fix 7: Debug Network Errors in Node.js

In Node.js (SSR, scripts, CLI), Axios errors include more detail because there’s no browser security restricting what you see:

axios.get('https://api.example.com/data')
  .catch(error => {
    if (error.code === 'ECONNREFUSED') {
      console.error('Server is not running or port is closed');
    } else if (error.code === 'ENOTFOUND') {
      console.error('DNS resolution failed — check the hostname');
    } else if (error.code === 'ETIMEDOUT') {
      console.error('Connection timed out');
    } else if (error.code === 'CERT_HAS_EXPIRED') {
      console.error('SSL certificate expired');
    } else {
      console.error('Error code:', error.code);
      console.error('Error message:', error.message);
    }
  });

Enable Axios debug logging in Node.js:

// Log request details
axios.interceptors.request.use(request => {
  console.log('Request:', request.method?.toUpperCase(), request.url);
  return request;
});

axios.interceptors.response.use(
  response => {
    console.log('Response:', response.status, response.config.url);
    return response;
  },
  error => {
    console.error('Error:', error.code, error.config?.url);
    return Promise.reject(error);
  }
);

Still Not Working?

Switch the adapter to isolate XHR-versus-fetch behavior. From Axios 1.6 onward, you can force a specific adapter at the instance or request level. If “Network Error” reproduces on one adapter but not the other, the cause is platform-specific — usually a CORS preflight that fetch handles differently from XHR:

const api = axios.create({
  baseURL: 'https://api.example.com',
  adapter: 'fetch',  // 'xhr' | 'http' | 'fetch'
});

Cancel stale requests with AbortController, not the deprecated CancelToken. If you upgraded from 0.27 to 1.x, leftover CancelToken.source() calls still work but can produce confusing “Network Error” messages when components unmount. Migrate to AbortController:

const controller = new AbortController();
axios.get('/api/data', { signal: controller.signal })
  .catch(err => {
    if (axios.isCancel(err)) return;  // Expected — component unmounted
    throw err;
  });

// Later
controller.abort();

Test the endpoint directly with curl:

curl -v https://api.example.com/data \
  -H "Authorization: Bearer your-token" \
  -H "Origin: https://app.example.com"

If curl works but Axios doesn’t, it’s CORS (browser-specific) or an extension blocking the request.

Check for ad blockers. Temporarily disable all browser extensions and retry. If it works without extensions, the request URL matches an ad-blocker rule.

Verify the base URL. A common mistake is a wrong baseURL in the Axios instance combined with a relative URL:

const api = axios.create({ baseURL: 'https://api.example.com/v1' });

// Resolves to: https://api.example.com/v1/users ✓
api.get('/users');

// Resolves to: https://api.example.com/users (note: /v1 is removed!)
api.get('users');  // Missing leading slash — resolves relative to baseURL

// Resolves to: https://other.example.com/data (ignores baseURL entirely)
api.get('https://other.example.com/data');

Check the proxy if you’re using one. Reverse proxies (nginx, Cloudflare, AWS API Gateway) sometimes strip CORS headers or apply their own timeout that’s shorter than Axios’s. If the response never reaches the browser, Axios reports “Network Error” with no clue that the proxy intercepted it. Test the same endpoint by bypassing the proxy from the same network.

Inspect error.config for misrouted requests. A wrong baseURL or a typo in the request URL produces an ENOTFOUND in Node and a generic “Network Error” in the browser. Logging error.config.url and error.config.baseURL together tells you the exact URL Axios tried:

api.get('/users').catch(err => {
  console.log('URL:', err.config?.baseURL, err.config?.url);
  console.log('Code:', err.code);
});

For related issues, see Fix: Express CORS Not Working, Fix: Flask CORS Not Working, Fix: CORS Preflight Request Blocked, and Fix: Next.js CORS Error.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles