When building Node.js applications that make external network requests (like HTTP APIs or database connections), you might encounter frustrating errors such as ECONNRESET or ETIMEDOUT. These are network-level errors that often confuse developers because they can be caused by multiple factors.
This guide explains what these errors mean, their root causes, and how to fix them step by step.
What Do These Errors Mean?
- ECONNRESET
-
This means the connection was forcibly closed by the remote host. For example, if you try to connect to a server and it resets the connection (drops it unexpectedly), Node.js throws
ECONNRESET
.
- ETIMEDOUT
- This means the request took too long and the connection timed out. Node.js closes the request because it didn’t receive a response within the allowed time.
Common Causes of ECONNRESET and ETIMEDOUT
- Server is overloaded and drops connections.
- Firewall / Proxy issues blocking connections.
- DNS resolution problems.
- Too many open sockets in Node.js (socket exhaustion).
- Timeout not configured properly in your HTTP client.
- Slow or unstable internet connection.
Step 1: Add Proper Error Handling
Always handle network errors gracefully in Node.js:
const https = require('https');
https.get('https://example.com', (res) => {
console.log(`Status Code: ${res.statusCode}`);
}).on('error', (err) => {
if (err.code === 'ECONNRESET') {
console.error('Connection was reset by server.');
} else if (err.code === 'ETIMEDOUT') {
console.error('Connection timed out.');
} else {
console.error('Error:', err.message);
}
});
Step 2: Increase Request Timeout
By default, Node.js sockets may close too quickly. Configure a custom timeout:
const https = require('https');
const options = {
hostname: 'example.com',
port: 443,
path: '/',
method: 'GET',
timeout: 10000 // 10 seconds
};
const req = https.request(options, (res) => {
res.on('data', (chunk) => {
console.log(`Data: ${chunk}`);
});
});
req.on('timeout', () => {
console.error('Request timed out');
req.destroy(); // Close request properly
});
req.on('error', (err) => {
console.error('Error:', err.code);
});
req.end();
Step 3: Use Connection Keep-Alive
Frequent socket creation can cause connection resets. Use agentkeepalive
or Node’s built-in agent:
const https = require('https');
const agent = new https.Agent({ keepAlive: true });
https.get('https://example.com', { agent }, (res) => {
console.log('Connection re-used successfully');
});
Step 4: Limit Concurrent Connections
Too many parallel requests can overwhelm either your Node.js app or the remote server.
Use a request queue or libraries like p-limit:
const pLimit = require('p-limit');
const limit = pLimit(5); // max 5 concurrent requests
const fetch = (url) => new Promise((resolve, reject) => {
https.get(url, (res) => {
resolve(res.statusCode);
}).on('error', reject);
});
(async () => {
const urls = ['https://example.com', 'https://google.com'];
const results = await Promise.all(urls.map(url => limit(() => fetch(url))));
console.log(results);
})();
Step 5: Fix DNS Resolution Issues
Sometimes DNS lookup delays cause ETIMEDOUT. Use Google DNS (8.8.8.8) or Cloudflare DNS (1.1.1.1).
Or resolve manually:
const dns = require('dns');
dns.lookup('example.com', (err, address) => {
if (err) throw err;
console.log('IP Address:', address);
});
Step 6: Tune Node.js Socket Settings
Increase the maximum number of sockets:
const https = require('https');
https.globalAgent.maxSockets = 100; // default is Infinity but sometimes libraries set it lower
Step 7: Check Server-Side Issues
If errors persist, the problem may be on the server you’re connecting to:
- Check server logs for dropped connections.
- Increase server timeout settings.
- Optimize API performance.
Best Practices to Avoid These Errors
- Always set timeouts on outgoing requests.
- Use retry logic with exponential backoff for unstable connections.
- Enable keep-alive for persistent connections.
- Monitor socket usage (
lsof -i :PORT
ornetstat
). - Deploy a load balancer if you’re handling many concurrent users.
Conclusion
The ECONNRESET and ETIMEDOUT errors in Node.js are usually caused by improper request handling, network instability, or server-side issues. By setting timeouts, enabling keep-alive, limiting concurrency, and adding retries, you can make your Node.js applications resilient and production-ready.
Related Guides
- Learn to configure domains, set up Nginx, and install free SSL certificates to make your Ionic blog secure and SEO-friendly.
- Build portable and scalable apps effortlessly by packaging your entire Ionic and Node.js stack into containers.
- A step-by-step tutorial to set up CI/CD pipelines for SSH deployment and Firebase Hosting using GitHub Actions.
- Easily deploy and manage your apps on DigitalOcean using PM2 and Nginx for high availability and performance.
0 Comments