softonic/axios-retry · error
ECONNABORTED
ECONNABORTED
Error message
ECONNABORTED
What it means
ECONNABORTED is set by axios when a request fails because its configured timeout elapsed, or the underlying socket/connection was aborted mid-flight (distinct from ECONNREFUSED/ECONNRESET which are refused/reset connections). At src/index.ts:96 axios-retry places 'ECONNABORTED' in CODE_EXCLUDE_LIST inside isNetworkError, so a timed-out request is deliberately NOT classified as a network error and the default retryCondition will not retry it. The inline comment at src/index.ts:103 ('Prevents retrying timed out & cancelled requests') documents this as intended behavior — a timeout is treated as a possibly-slow endpoint rather than a transient blip.
Source
Thrown at src/index.ts:116: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
- Raise the request timeout to comfortably exceed the endpoint's observed p99 latency (measure first, don't guess).
- Set shouldResetTimeout: true in the axios-retry options so each retry attempt gets a fresh full timeout budget instead of sharing the original.
- Provide a custom retryCondition that returns true for error.code === 'ECONNABORTED' on idempotent verbs if you specifically want timeouts retried.
- Investigate server-side latency or intermediary proxies/LBs if timeouts are chronic — retrying a genuinely slow endpoint just amplifies load.
- Check for a custom httpAgent/httpsAgent with its own timeout that is shorter than config.timeout.
Example fix
// before
axiosRetry(client, { retries: 3 }); // default: timeouts NOT retried
await client.get('/slow', { timeout: 2000 }); // -> ECONNABORTED, no retry
// after
axiosRetry(client, {
retries: 3,
shouldResetTimeout: true, // fresh budget per attempt
retryCondition: (err) =>
axiosRetry.isNetworkOrIdempotentRequestError(err) ||
(err.code === 'ECONNABORTED' &&
['get', 'head', 'options', 'put', 'delete'].includes(
err.config?.method ?? ''
)),
});
await client.get('/slow', { timeout: 10000 }); Defensive patterns
Strategy: validation
Validate before calling
// Validate the timeout is sane relative to observed latency BEFORE sending.
function buildConfig(url, { timeout = 5000 } = {}) {
const p99 = latencyP99MsFor(url); // your metrics source
if (timeout <= p99) {
console.warn(`timeout ${timeout}ms < p99 ${p99}ms for ${url}; raising`);
timeout = Math.ceil(p99 * 2);
}
return { timeout };
} Type guard
import type { AxiosError } from 'axios';
function isTimeoutError(error: unknown): error is AxiosError {
return (
typeof error === 'object' &&
error !== null &&
(error as AxiosError).code === 'ECONNABORTED' &&
!(error as AxiosError).response
);
} Try / catch
try {
await client.get('/slow', { timeout: 10000 });
} catch (err) {
if (err?.code === 'ECONNABORTED') {
// timeout — surface as a distinct, actionable error to the caller
throw new Error(`Request timed out after ${err.config?.timeout}ms`);
}
throw err;
} Prevention
- Measure p99 latency per endpoint and set timeout to at least 2-3x that.
- Set shouldResetTimeout: true whenever you retry, so the budget is per-attempt.
- Check any custom httpAgent/httpsAgent for a shorter timeout than config.timeout.
- After an axios 0.x -> 1.x upgrade, re-verify timeout behavior under proxies/agents.
- Alert on ECONNABORTED rate per endpoint to catch chronic slowness early.
When it happens
Trigger: A request whose AxiosRequestConfig.timeout (ms) is exceeded before the server responds, or whose socket is aborted, rejects with AxiosError code === 'ECONNABORTED' and no .response. The response interceptor calls isNetworkOrIdempotentRequestError -> isNetworkError, which returns false at src/index.ts:104 due to the CODE_EXCLUDE_LIST membership, so shouldRetry returns false and the error is rejected at src/index.ts:328 without any retry attempt.
Common situations: timeout config set lower than the endpoint's realistic p99 latency; high-latency or mobile networks; server-side processing (heavy query, cold start, large payload) exceeding the client timeout; a gateway/proxy/load-balancer with a shorter timeout than the client; shouldResetTimeout left at false (default) so cumulative retry delays eat the original timeout budget; recent axios 0.x -> 1.x upgrade where timeout semantics around proxies/agents changed.
Understand the failure class
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
Related errors
AI-assisted analysis of softonic/axios-retry@dd9b700dfb (2026-08-07).
Data as JSON: /api/errors/74c052ba517dace6.
Report an issue: GitHub.