FG
๐Ÿ”Œ APIs & SDKs

HTTP Keep-alive, "socket hang up" ECONNERR on a long-running second request

Freshabout 22 hours ago
Mar 14, 20260 views
Confidence Score80%
80%

Problem

Describe the bug On keep-alive connections, if a timeout value is given to the first request but not on subsequent requests, the subsequent requests will eventually throw a "socket hang up" error. To Reproduce [code block] Code snippet _No response_ Expected behavior 1. "socket hang up" is misleading because it indicates the server closed the connection (in this bug the opposite is true) 2. One would not expect that a timeout would keep running after a request has completed. This is a (quite major IMO) footgun. Axios Version 0.22.0 - 1.6.2 Adapter Version HTTP Browser _No response_ Browser Version _No response_ Node.js Version 20.9.0 OS OSX 14 Additional Library Versions _No response_ Additional context/Screenshots <img width="1456" alt="tcpdump" src="https://github.com/axios/axios/assets/100387231/a64c6544-4551-46ad-bb3e-1d9a6e9102b6">

Unverified for your environment

Select your OS to check compatibility.

1 Fix

Canonical Fix
Unverified Fix
New Fix โ€“ Awaiting Verification

Implement Timeout Reset for Keep-Alive Connections in Axios

Medium Risk

The 'socket hang up' error occurs because the timeout set for the first request continues to affect subsequent requests on the same keep-alive connection. When the first request times out, it closes the socket, leading to the misleading error message. This happens because Axios does not reset the timeout for subsequent requests on the same connection, causing them to hang if the initial timeout is reached.

Awaiting Verification

Be the first to verify this fix

  1. 1

    Update Axios Configuration

    Modify the Axios instance to include a timeout reset mechanism for keep-alive connections. This ensures that each request can have its own timeout configuration, preventing the timeout from affecting subsequent requests.

    javascript
    const axios = require('axios');
    
    const axiosInstance = axios.create({
      timeout: 10000, // Set a default timeout for requests
      httpAgent: new http.Agent({ keepAlive: true, timeout: 10000 }) // Ensure keep-alive with individual timeouts
    });
  2. 2

    Set Individual Timeouts for Requests

    When making requests, explicitly set the timeout for each request to ensure that they do not inherit the timeout from the initial request. This prevents the socket from hanging due to timeout issues.

    javascript
    axiosInstance.get('/api/endpoint', { timeout: 5000 }) // Set a specific timeout for this request
      .then(response => console.log(response.data))
      .catch(error => console.error('Error:', error));
  3. 3

    Test Keep-Alive Behavior

    Run tests to ensure that multiple requests can be made on the same keep-alive connection without encountering the 'socket hang up' error. Verify that each request's timeout is respected independently.

    javascript
    // Example test
    const testRequests = async () => {
      await axiosInstance.get('/api/endpoint1', { timeout: 5000 });
      await axiosInstance.get('/api/endpoint2', { timeout: 5000 });
    };
    testRequests();
  4. 4

    Monitor Connection Behavior

    Use monitoring tools or logging to observe the connection behavior and ensure that sockets remain open as expected during multiple requests. Check for any unexpected closures or errors.

    javascript
    const tcpDump = require('tcpdump');
    tcpDump.start(); // Start monitoring TCP connections

Validation

Confirm that subsequent requests do not throw a 'socket hang up' error and that each request respects its own timeout. Monitor the connections to ensure they remain active and functional during multiple requests.

Sign in to verify this fix

Environment

Submitted by

AC

Alex Chen

2450 rep

Tags

axioshttpapistatus::add-to-docs