Guide
Diagnosing Axios Request Timeout Problems in JavaScript and Node.js
A step‑by‑step diagnostic guide for identifying and fixing Axios request timeout issues in browser and Node.js environments.
Published by Tasadduq Burney
21 Jul 2025, 04:08 UTC
3 min144.7K views0

Recognizable Condition
An Axios request appears to hang, fails with a timeout error, or behaves differently between browser and Node.js environments.
Cause & Diagnostic Table
| Condition | Likely Cause | Quick Check | Suggested Fix |
|---|---|---|---|
| Request exceeds expected time or never resolves | Missing or insufficient timeout setting | Inspect axios.defaults.timeout and any per‑call timeout option | Set a sensible timeout, e.g. axios.defaults.timeout = 5000 or pass { timeout: 5000 } to the call |
| Timeout errors occur even after configuring timeout | Interceptor or custom adapter overriding config.timeout | Search request/response interceptors for assignments to config.timeout | Ensure interceptors preserve the original timeout or explicitly restore it after modification |
| Timeouts only appear in Node.js, not in the browser | Node’s socket timeout differs from browser’s AbortController mechanism | Verify whether the request uses the http/https adapter and if socket.timeout is set | Set axios.defaults.timeout and optionally configure httpAgent/httpsAgent with matching timeout, or rely on the built‑in adapter |
| Cancelled requests are logged as timeout errors | Using AbortController without distinguishing cancellation from timeout | Catch the error and test axios.isCancel(error) or error.code === 'ERR_CANCELED' | Handle cancellation separately before treating the error as a timeout |
| Timeout not respected during large uploads/downloads | Timeout only limits time to receive response headers, not data transfer | Monitor onDownloadProgress/onUploadProgress events; see if data stalls after headers | Implement an idle‑timer based on progress events or use a streaming approach with a separate timeout |
Ordered Checks
- Check global defaults:
console.log(axios.defaults.timeout). - Inspect the specific call for a
timeoutoverride. - Review all request and response interceptors for changes to
config.timeout. - Confirm the runtime environment (browser vs. Node) and adapter in use.
- If using
AbortController, verify error discrimination logic. - For large transfers, add progress listeners and measure idle time.
Fixes Tied to Findings
- Missing timeout:
import axios from 'axios'; axios.defaults.timeout = 7000; // 7 seconds - Interceptor overwriting timeout:
axios.interceptors.request.use(config => { // preserve existing timeout if present const timeout = config.timeout ?? axios.defaults.timeout; // … other logic … return { ...config, timeout }; }); - Node‑specific socket timeout:
import { Agent } from 'https'; const httpsAgent = new Agent({ timeout: 6000 }); axios.defaults.httpsAgent = httpsAgent; axios.defaults.timeout = 6000; - Distinguishing cancellation:
axios.get('/slow', { signal: abortController.signal }) .catch(err => { if (axios.isCancel(err)) { console.log('Request was cancelled'); } else if (err.code === 'ECONNABORTED') { console.log('Request timed out'); } }); - Progress‑based idle timeout for uploads/downloads:
let lastActivity = Date.now(); const IDLE_LIMIT = 10000; // 10 ms axios.post('/upload', formData, { onUploadProgress: e => { lastActivity = Date.now(); }, }).catch(err => { if (Date.now() - lastActivity > IDLE_LIMIT) { console.log('Upload stalled – treating as timeout'); } });
Escalation Criteria
If after applying the above checks and fixes the request still does not abort as expected:
- Verify the Axios version (
v0.xvs.v1.x) – timeout handling changed between major releases. - Test in a minimal reproduction that isolates the Axios call from other libraries.
- Consider whether a custom adapter (e.g., for mocking or testing) respects the
timeoutoption; if not, adapt the adapter or switch to the default adapter. - In browsers lacking native
AbortController, ensure a polyfill is loaded.
Verification Steps
- Create a test endpoint that delays the response longer than the configured timeout (e.g.,
setTimeout(() => res.send(), 8000)). - Make an Axios request with
timeout: 5000and measure elapsed time usingperformance.now()(browser) orprocess.hrtime.bigint()(Node). - Assert that the thrown error has
error.code === 'ECONNABORTED'and that the measured time is close to the timeout value (± 200 ms). - Repeat the test in both a modern browser and a Node.js process to confirm consistent behavior.
Limitations
- Timeout only aborts the wait for response headers; it does not limit the duration of data streaming unless additional idle‑timer logic is added.
- In older browsers without
AbortController, the timeout may fail unless a polyfill is present. - Custom adapters (e.g.,
axios-mock-adapter) might ignore thetimeoutsetting; check the adapter’s documentation. - Version‑specific differences: Axios v1 treats
timeoutas milliseconds for the entire request, while some v0.x versions applied it only to the connection phase.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.