softonic/axios-retry · warning

ERR_CANCELED

ERR_CANCELED

Error message

ERR_CANCELED

What it means

ERR_CANCELED is set by axios (not by axios-retry) on the rejected error when an in-flight request is aborted via an AbortController/AbortSignal (or a CancelToken in older axios). At src/index.ts:96 axios-retry places 'ERR_CANCELED' in CODE_EXCLUDE_LIST inside isNetworkError, so a canceled request is explicitly NOT classified as a network error and is therefore NOT retried by the default retryCondition. The rationale (see the inline comment 'Prevents retrying timed out & cancelled requests' at src/index.ts:103) is that cancellation represents deliberate user intent, not a transient failure worth retrying.

Source

Thrown at src/index.ts:104:96

  isNetworkError(error: AxiosError): boolean;
  isRetryableError(error: AxiosError): boolean;
  isSafeRequestError(error: AxiosError): boolean;
  isIdempotentRequestError(error: AxiosError): boolean;
  isNetworkOrIdempotentRequestError(error: AxiosError): boolean;
  exponentialDelay(retryCount?: number, error?: AxiosError, delayFactor?: number): number;
  linearDelay(delayFactor?: number): (retryCount: number, error: AxiosError | undefined) => number;
}

declare module 'axios' {
  export interface AxiosRequestConfig {
    'axios-retry'?: IAxiosRetryConfigExtended;
  }
}

export const namespace = 'axios-retry';

export function isNetworkError(error) {
  const CODE_EXCLUDE_LIST = ['ERR_CANCELED', 'ECONNABORTED'];
  if (error.response) {
    return false;
  }
  if (!error.code) {
    return false;
  }
  // Prevents retrying timed out & cancelled requests
  if (CODE_EXCLUDE_LIST.includes(error.code)) {
    return false;
  }
  // Prevents retrying unsafe errors
  return isRetryAllowed(error);
}

const SAFE_HTTP_METHODS = ['get', 'head', 'options'];
const IDEMPOTENT_HTTP_METHODS = SAFE_HTTP_METHODS.concat(['put', 'delete']);

export function isRetryableError(error: AxiosError): boolean {

View on GitHub (pinned to dd9b700dfb)

Solutions

  1. If the cancel was intentional, treat ERR_CANCELED as expected control flow: catch it and swallow/ignore it rather than surfacing it as an error to the user.
  2. If you DO want canceled requests to be retried, supply a custom retryCondition that returns true for error.code === 'ERR_CANCELED' in the appropriate context (e.g. only when the abort was not user-initiated).
  3. Make sure you are not aborting a shared AbortController unintentionally — give each in-flight request its own controller unless you genuinely mean to cancel a whole batch.
  4. Do not reuse the same AbortController across retries: axios-retry forwards config.signal into each retry (src/index.ts:273-289), so aborting between retries short-circuits the retry loop.
  5. Verify no upstream interceptor or wrapper is auto-aborting on every response (some logging/cancel plugins do this).

Example fix

// before
const data = await axios.get('/api/user', { signal: ctrl.signal });
// caller aborts via ctrl.abort() on unmount -> uncaught ERR_CANCELED

// after
try {
  const { data } = await axios.get('/api/user', { signal: ctrl.signal });
} catch (err) {
  if (axios.isCancel?.(err) || err.code === 'ERR_CANCELED') {
    // expected: caller (or component unmount) cancelled intentionally
    return;
  }
  throw err; // real error, re-throw
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before issuing the request, confirm the signal has not already been aborted.
import { isCancel } from 'axios';

async function safeGet(url, signal) {
  if (signal?.aborted) {
    return undefined; // nothing to do — already cancelled
  }
  return axios.get(url, { signal });
}

Type guard

import type { AxiosError } from 'axios';

function isCanceledError(error: unknown): error is AxiosError {
  return (
    typeof error === 'object' &&
    error !== null &&
    (error as AxiosError).code === 'ERR_CANCELED'
  );
}

Try / catch

try {
  await client.get('/api/user', { signal: ctrl.signal });
} catch (err) {
  // ERR_CANCELED is intentional control flow, not a failure.
  if (err?.code === 'ERR_CANCELED' || axios.isCancel?.(err)) return;
  throw err;
}

Prevention

When it happens

Trigger: A caller passes signal: abortController.signal in the AxiosRequestConfig of a request, then calls abortController.abort() while the request is still pending. Axios rejects with an AxiosError whose code === 'ERR_CANCELED' and no .response. The axios-retry response interceptor (src/index.ts:311) runs; shouldRetry -> isNetworkOrIdempotentRequestError -> isNetworkError returns false at src/index.ts:104 because the code is in CODE_EXCLUDE_LIST, so no retry is scheduled and the error is re-thrown via Promise.reject at src/index.ts:328.

Common situations: React/Vue/Svelte components aborting fetches on unmount; a debounced search where each new keystroke cancels the previous in-flight request; an AbortController accidentally shared across multiple requests so aborting one cancels siblings; migration from the deprecated axios CancelToken to AbortController; race-condition where a parent caller aborts because a newer request superseded the old one.

Related errors


AI-assisted analysis of softonic/axios-retry@dd9b700dfb (2026-08-07). Data as JSON: /api/errors/31a7b43c99fe495f. Report an issue: GitHub.