What the error looks like
It surfaces on the reading side of a connection that vanished:
Error: read ECONNRESET
at TCP.onStreamRead (node:internal/stream_base_commons:217:20)
errno: -104, code: 'ECONNRESET', syscall: 'read'
# via an HTTP client it often reads as:
Error: socket hang up (code: 'ECONNRESET')
"Reset" is different from "refused": the connection was established, then the other end tore it down. That points at a connection that went stale or an upstream that died, not a wrong address.
Why it happens
A reused keep-alive socket went stale
Your client reused a pooled connection the server had already closed, so the first write resets.
The upstream restarted mid-request
A deploy, scale-down, or crash on the other side severed connections that were in flight.
A proxy idle-timeout fired
A load balancer or proxy closed an idle connection your client still thought was open.
The server dropped you on purpose
A rate limiter, max-body guard, or WAF reset the connection instead of replying.
Diagnose it in three steps
Find which host resets
# Log the request target on error so you know who hung up
# Is it always the same upstream? That narrows it fast.First request or only reused?
# If it only fails on the 2nd+ request to a host, it's stale keep-alive.
# If it fails right when you deploy the upstream, it's the restart.Compare the timeouts
# Server idle timeout must be >= client keep-alive timeout,
# or the client will keep grabbing sockets the server just closed.Make the client expect dead sockets
You can't stop a peer from ever closing a connection — so handle it. Keep idle sockets short-lived and retry safe requests:
const http = require('http');
const agent = new http.Agent({
keepAlive: true,
// give up on an idle socket BEFORE the upstream does
timeout: 30_000,
});
// Retry only idempotent requests (GET/PUT/DELETE), with backoff.
// Never blindly retry a POST that may have already been processed.
Deploys that drain instead of reset
A large share of production ECONNRESETs come from the upstream restarting mid-request on deploy. Infraveil is a hosted backend operations control plane for applications running on your own servers: its customer-side agent drains connections on the old instance before stopping it and shifts traffic only to a health-checked new one. Managed deploys can use the configured manual, exact-hash allowlist, or automatic approval mode; automatic mode removes a practical per-release veto. Recovery uses separately configured, bounded automation, and selected events are reported subject to component, retention, pagination, configuration, and reachability.
Frequently asked questions
What does ECONNRESET mean?
The remote end abruptly closed an established TCP connection (a "connection reset by peer"). Your side was mid-read or mid-write when the socket disappeared.
Is ECONNRESET my fault or the server's?
Often neither is "broken" — it's a stale pooled connection or an upstream that restarted. The durable fix lives on the client: short idle timeouts plus retries for idempotent requests.
How do I fix 'socket hang up' in axios?
Use a keep-alive agent with a timeout shorter than the upstream's, and add retry-with-backoff (e.g. axios-retry) for safe methods. Investigate the upstream if it correlates with its deploys.
ECONNRESET vs ECONNREFUSED?
Refused means nothing accepted the connection (service down / wrong port). Reset means a connection was established and then torn down by the other side.
Client-side, no signup — they run in your browser.