How to fix Error: socket hang up in Node.js

Node.jsINTERMEDIATEMEDIUMUpdated Dec 9, 2025· 303 views

A "socket hang up" error occurs when a network connection is unexpectedly closed or terminated before the operation completes. This typically happens during HTTP requests when a server closes the connection without properly finishing the response, or when the socket times out waiting for data.

Quick fix

Fixes ECONNRESET

const http = require('http');

function makeRequest(url, timeout = 30000) {
  return new Promise((resolve, reject) => {
    const req = http.get(url, (res) => {
      let data = '';
      res.on('data', (chunk) => {
        data += chunk;
      });
      res.on('end', () => {
        resolve(data);
      });
    });

    // Handle socket hang up errors
    req.on('error', (err) => {
      if (err.code === 'ECONNRESET' || err.message === 'socket hang up') {
        console.error('Socket hang up detected, retrying...');
        reject(err);
      } else {
        reject(err);
      }
    });

    // Set a timeout for the request
    req.setTimeout(timeout, () => {
      req.destroy();
      reject(new Error('Request timeout - socket hung up'));
    });
  });
}

// Usage with retry logic
async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await makeRequest(url);
    } catch (err) {
      if (i === maxRetries - 1) throw err;
      console.log(`Attempt ${i + 1} failed, retrying...`);
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}
  1. Add proper error handling to catch socket hang up errors
  2. Ensure you call req.end() on client requests and res.end() on server responses
  3. Increase socket timeout and set appropriate keep-alive settings
  4. Verify correct protocol usage (http vs https)
node.js — error
const http = require('http');
function makeRequest(url, timeout = 30000) {
return new Promise((resolve, reject) => {
const req = http.get(url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
resolve(data);
});
});
// Handle socket hang up errors
req.on('error', (err) => {
if (err.code === 'ECONNRESET' || err.message === 'socket hang up') {
console.error('Socket hang up detected, retrying...');
reject(err);
} else {
reject(err);
}
});
// Set a timeout for the request
req.setTimeout(timeout, () => {
req.destroy();
reject(new Error('Request timeout - socket hung up'));
});
});
}
// Usage with retry logic
async function fetchWithRetry(url, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await makeRequest(url);
} catch (err) {
if (i === maxRetries - 1) throw err;
console.log(`Attempt ${i + 1} failed, retrying...`);
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}
Error: socket hang up

What this error means

The "socket hang up" error indicates that the underlying TCP socket connection was closed abruptly or the other end of the connection stopped responding before the operation finished. Unlike ECONNRESET (which is a forceful reset), a socket hang up can occur when the connection simply ends without any data being exchanged for a period of time, or when a server closes the socket prematurely. In Node.js, this manifests as "Error: socket hang up" and typically includes the error code ECONNRESET. The error occurs when the client is waiting for a response from the server, but the server closes or the connection times out before the complete response is received. This is a common issue with HTTP keep-alive connections, long-running requests, and when dealing with slow networks or unresponsive servers. The socket hang up is a network-level error that signals either a timeout, an incomplete response, or a connection unexpectedly terminated by the remote server. This is distinct from properly closed connections (which emit an 'end' event) and is always treated as an error condition.

Typical symptoms

  • Requests intermittently fail with "Error: socket hang up"
  • Errors occur more frequently when making requests to slow or overloaded servers
  • Long-running requests (uploads, downloads) fail partway through
  • External API calls fail after a few seconds of waiting
  • The error happens more often under high network latency
  • Consecutive requests to the same server eventually fail with socket hang up
  • Database connection timeouts showing as socket hang up errors
  • WebSocket connections drop with socket hang up messages

Common causes

  1. Server timeout exceeded while waiting for a response
  2. Server connection pool exhausted, causing it to drop new connections
  3. Network instability or packet loss causing the connection to stall
  4. Server process crashed or restarted without properly closing the socket
  5. Request not properly terminated with req.end() on the client side
  6. Response not properly sent with res.end() on the server side
  7. Firewall or proxy timing out idle connections
  8. Using the wrong protocol (http instead of https or vice versa)
  9. Server overload causing connections to be dropped prematurely
  10. Client timeout setting too short for the operation duration
  11. Socket destroyed while request is still in progress
  12. Memory pressure on server causing connection cleanup

How to fix "Error: socket hang up"

1Add proper error handling to catch socket hang up errors

Implement error handling on both client and server to gracefully handle socket hang up errors:

javascript
const http = require('http');

function makeRequest(url, timeout = 30000) {
  return new Promise((resolve, reject) => {
    const req = http.get(url, (res) => {
      let data = '';
      res.on('data', (chunk) => {
        data += chunk;
      });
      res.on('end', () => {
        resolve(data);
      });
    });

    // Handle socket hang up errors
    req.on('error', (err) => {
      if (err.code === 'ECONNRESET' || err.message === 'socket hang up') {
        console.error('Socket hang up detected, retrying...');
        reject(err);
      } else {
        reject(err);
      }
    });

    // Set a timeout for the request
    req.setTimeout(timeout, () => {
      req.destroy();
      reject(new Error('Request timeout - socket hung up'));
    });
  });
}

// Usage with retry logic
async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await makeRequest(url);
    } catch (err) {
      if (i === maxRetries - 1) throw err;
      console.log(`Attempt ${i + 1} failed, retrying...`);
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
    }
  }
}
2Ensure you call req.end() on client requests and res.end() on server responses

A common cause of socket hang up is not properly terminating requests and responses. Always call end() to complete the operation:

javascript
// Client: Always call req.end() to close the request
const http = require('http');

const postData = JSON.stringify({ name: 'John' });

const options = {
  hostname: 'example.com',
  port: 80,
  path: '/api/user',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(postData)
  }
};

const req = http.request(options, (res) => {
  let data = '';
  res.on('data', (chunk) => {
    data += chunk;
  });
  res.on('end', () => {
    console.log('Response received:', data);
  });
});

req.on('error', (err) => {
  console.error('Request error:', err.message);
});

// CRITICAL: Always end the request
req.write(postData);
req.end();
javascript
// Server: Always call res.end() to close the response
const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write('Processing your request...\n');

  // Simulate some processing
  setTimeout(() => {
    res.write('Done!\n');
    // CRITICAL: Always end the response
    res.end();
  }, 1000);
});

server.listen(3000);
3Increase socket timeout and set appropriate keep-alive settings

Configure socket timeouts and keep-alive options to prevent premature disconnections:

javascript
const http = require('http');
const https = require('https');

// Create an agent with proper timeout settings
const httpAgent = new http.Agent({
  keepAlive: true,
  keepAliveMsecs: 30000,  // Keep alive every 30 seconds
  timeout: 60000,         // 60 second socket timeout
  maxSockets: 50,
  maxFreeSockets: 10,
  freeSocketTimeout: 30000, // Free socket timeout
});

const httpsAgent = new https.Agent({
  keepAlive: true,
  keepAliveMsecs: 30000,
  timeout: 60000,
  maxSockets: 50,
  maxFreeSockets: 10,
  freeSocketTimeout: 30000,
});

// Use agents in requests
const options = {
  hostname: 'example.com',
  path: '/api/data',
  agent: httpAgent,
};

http.get(options, (res) => {
  // Handle response
  res.on('data', () => {});
  res.on('end', () => console.log('Complete'));
});

For axios:

javascript
const axios = require('axios');
const http = require('http');
const https = require('https');

const client = axios.create({
  httpAgent: new http.Agent({
    keepAlive: true,
    timeout: 60000,
  }),
  httpsAgent: new https.Agent({
    keepAlive: true,
    timeout: 60000,
  }),
  timeout: 30000, // Request timeout
});

client.get('https://api.example.com/data')
  .then(res => console.log(res.data))
  .catch(err => console.error(err.message));
4Verify correct protocol usage (http vs https)

A common cause of socket hang up is using the wrong protocol. Ensure you use https module for HTTPS URLs and http for HTTP:

javascript
const http = require('http');
const https = require('https');
const url = require('url');

function fetchUrl(urlString) {
  return new Promise((resolve, reject) => {
    const parsed = url.parse(urlString);

    // Use https for HTTPS URLs, http for HTTP URLs
    const protocol = parsed.protocol === 'https:' ? https : http;

    const req = protocol.get(parsed, (res) => {
      let data = '';
      res.on('data', (chunk) => {
        data += chunk;
      });
      res.on('end', () => {
        resolve(data);
      });
    });

    req.on('error', (err) => {
      reject(err);
    });

    req.end();
  });
}

// This will work correctly for both HTTP and HTTPS URLs
fetchUrl('https://example.com/api')
  .then(data => console.log(data))
  .catch(err => console.error('Socket hang up:', err.message));
5Implement retry logic with exponential backoff

Socket hang ups are often transient, so implementing retry logic is critical for reliability:

javascript
async function fetchWithExponentialBackoff(url, options = {}, maxRetries = 3) {
  let lastError;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 30000);

      const response = await fetch(url, {
        ...options,
        signal: controller.signal,
      });

      clearTimeout(timeout);

      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }

      return response;
    } catch (err) {
      lastError = err;

      const isRetriable =
        err.message === 'socket hang up' ||
        err.code === 'ECONNRESET' ||
        err.code === 'ETIMEDOUT' ||
        err.code === 'ECONNREFUSED' ||
        err.name === 'AbortError';

      if (!isRetriable || attempt === maxRetries) {
        throw err;
      }

      // Exponential backoff: 1s, 2s, 4s, etc.
      const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
      console.log(`Attempt ${attempt + 1} failed (${err.message}), retrying in ${delay}ms...`);

      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }

  throw lastError;
}

// Usage
fetchWithExponentialBackoff('https://api.example.com/data')
  .then(res => res.json())
  .then(data => console.log('Success:', data))
  .catch(err => console.error('Failed after all retries:', err.message));
6Configure server timeouts if you control the server

If running a Node.js server, configure proper timeout values to prevent socket hang ups on the client side:

javascript
const http = require('http');

const server = http.createServer((req, res) => {
  // Simulate processing
  setTimeout(() => {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ success: true }));
  }, 100);
});

// Configure timeouts on the server
server.keepAliveTimeout = 65000;      // 65 seconds
server.headersTimeout = 66000;        // 66 seconds (slightly more than keepAliveTimeout)
server.timeout = 120000;              // 2 minutes overall timeout

// Handle client connection timeouts
server.on('clientError', (err, socket) => {
  if (err.code === 'ECONNRESET' || err.message === 'socket hang up') {
    console.log('Client socket hang up detected');
    if (socket.writable) {
      socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
    }
  } else if (err.code !== 'EPIPE') {
    console.error('Unexpected client error:', err);
    socket.end('HTTP/1.1 500 Internal Server Error\r\n\r\n');
  }
});

server.listen(3000, () => {
  console.log('Server running on port 3000');
});

For Express:

javascript
const express = require('express');
const app = express();

app.get('/api/data', (req, res) => {
  res.json({ data: 'example' });
});

const server = app.listen(3000, () => {
  console.log('Server running on port 3000');
});

// Configure timeouts
server.keepAliveTimeout = 65000;
server.headersTimeout = 66000;

// Handle socket errors
server.on('clientError', (err, socket) => {
  if (err.message === 'socket hang up') {
    console.log('Client hung up');
  }
});
7Use connection pooling libraries for consistent connections

For repeated requests to the same server, use a connection pooling library to maintain stable connections:

bash
npm install agentkeepalive
javascript
const http = require('http');
const https = require('https');
const Agent = require('agentkeepalive');

// Create agents with proper pooling
const httpAgent = new Agent({
  keepAlive: true,
  maxSockets: 100,
  maxFreeSockets: 10,
  timeout: 60000,
  freeSocketTimeout: 30000,
  keepAliveTimeout: 60000,
  socketActiveTTL: 110000,
});

const httpsAgent = new Agent.HttpsAgent({
  keepAlive: true,
  maxSockets: 100,
  maxFreeSockets: 10,
  timeout: 60000,
  freeSocketTimeout: 30000,
  keepAliveTimeout: 60000,
  socketActiveTTL: 110000,
});

// Use with axios or node-fetch
const axios = require('axios');

const client = axios.create({
  httpAgent,
  httpsAgent,
  timeout: 30000,
});

// Now make requests - socket hang ups should be rare
client.get('https://api.example.com/data')
  .then(res => console.log('Success'))
  .catch(err => console.error('Error:', err.message));

Advanced notes

Socket Hang Up vs ECONNRESET:
While often shown with ECONNRESET error code, "socket hang up" and ECONNRESET are slightly different. ECONNRESET is a forced TCP reset, while socket hang up is a graceless termination or timeout. Both should be handled identically - with retries and proper timeout configuration.

Node.js Version Considerations:
Node.js versions 19+ have had reported issues with consecutive HTTP requests causing socket hang up errors, particularly with node-fetch. If experiencing persistent issues, check your Node.js version and consider upgrading or downgrading to find a stable version for your use case.

Keep-Alive Connection Lifecycle:
Socket hang up errors are most common with HTTP keep-alive enabled. Servers close idle keep-alive connections after a timeout (typically 5-65 seconds). If a client tries to reuse a socket just after the server has closed it, a socket hang up occurs. The solution is configuring timeouts so the client closes idle sockets slightly before the server does.

Network Intermediaries:
Proxies, load balancers, firewalls, and CDNs can cause socket hang ups by enforcing their own timeout rules. AWS ALB defaults to 60-second idle timeout, while many corporate firewalls reset connections after 30-60 seconds. In restricted networks, use shorter timeout values and implement aggressive retry logic.

Long-Running Operations:
For operations that take longer than typical socket timeouts (file uploads, downloads, streaming, database operations), explicitly increase the timeout and consider splitting the operation into smaller chunks. Long requests should have heartbeat mechanisms to keep the connection alive.

Debugging Socket Hang Ups:
Enable Node.js HTTP debugging with NODE_DEBUG=http to see the raw HTTP protocol exchange. Use network tools like tcpdump, Wireshark, or strace to see when and why the connection closes. Correlate client-side socket hang up errors with server-side logs to determine which side initiated the closure.

Cloud Environment Quirks:
Serverless and containerized environments often have aggressive network timeouts. AWS Lambda has a 900-second execution timeout but may have stricter socket timeouts. Docker containers may inherit host network timeout settings. When deploying to cloud, test socket hang up scenarios thoroughly.

Frequently asked questions

What does "ECONNRESET" mean?
The "socket hang up" error indicates that the underlying TCP socket connection was closed abruptly or the other end of the connection stopped responding before the operation finished. Unlike ECONNRESET (which is a forceful reset), a socket hang up can occur when the connection simply ends without any data being exchanged for a period of time, or when a server closes the socket prematurely. js, this manifests as "Error: socket hang up" and typically includes the error code ECONNRESET.
How do I fix "ECONNRESET"?
A "socket hang up" error occurs when a network connection is unexpectedly closed or terminated before the operation completes. This typically happens during HTTP requests when a server closes the connection without properly finishing the response, or when the socket times out waiting for data.
What causes "ECONNRESET"?
Server timeout exceeded while waiting for a response Server connection pool exhausted, causing it to drop new connections Network instability or packet loss causing the connection to stall
Is the "ECONNRESET" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading