AxiosError: Request failed with status code 401

Node.js · updated 2026-11-03

Thrown by axios when the server answers with a status outside 200-299. The request itself worked: the useful detail (the API's error message) is in error.response.data, which the default log line leaves out.

AxiosError: Request failed with status code 401
    at settle (file:///app/node_modules/axios/lib/core/settle.js:19:12)
    at IncomingMessage.handleStreamEnd (file:///app/node_modules/axios/lib/adapters/http.js:599:11)
    at Axios.request (file:///app/node_modules/axios/lib/core/Axios.js:45:41)
    at async syncInvoices (file:///app/src/billing.js:31:18) {
  code: 'ERR_BAD_REQUEST',
  status: 401,
  ...
}

Quick fix

Log error.response.status, error.response.data and error.config.url: the API usually says exactly what is wrong. Then fix by status: 401 means the credentials are missing or wrong, 403 means not allowed, 404 means a wrong URL or id, 429 means slow down, 5xx means retry later.

  1. Catch the error and log status, the response body and the request URL (not the whole error object).
  2. 401: check the token is set in this environment and sent in the right header format.
  3. 403: the credentials work but lack permission or scope for that resource.
  4. 404: compare the URL and ids with the API docs; base URLs often differ between test and live.
  5. 429 and 5xx: retry with backoff, honoring a Retry-After header when present.
typescript
import axios from 'axios';

try {
  const { data } = await api.get(`/invoices/${id}`);
  return data;
} catch (err) {
  if (axios.isAxiosError(err) && err.response) {
    logger.warn('API error', {
      url: err.config?.url,
      status: err.response.status,
      body: err.response.data, // the API's own error message
    });
    if (err.response.status === 404) return null;
  }
  throw err;
}

Why it happens

Missing or expired credentials (401)

An API key that is not set in production, a bearer token that expired, or "Bearer" missing from the Authorization header all return 401.

Wrong URL, id or environment (404)

A test-mode id used against the live API, a trailing slash, or a base URL pointing at the wrong version returns 404 even though the code is right.

Rate limits (429)

Bursts of requests, retries without backoff, or many workers sharing one key push past the API limit.

Validation errors (400, 422)

The body or query does not match what the API expects; the response body names the field.

Other fixes

  • Set validateStatus on the client if some non-2xx responses (like 404) are normal for your flow.
  • Avoid logging the whole AxiosError: it includes the request config and can leak Authorization headers.

Same error, other wording

  • AxiosError: Request failed with status code 404
  • AxiosError: Request failed with status code 429
  • AxiosError: Request failed with status code 500

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the AxiosError "Request failed with status code" errors in production, group them by URL and status, show me the API response body for each group, and fix the cause (credentials, URL, retries).

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Axios docs: handling errors, MDN: HTTP response status codes