Deploy Error Decoder

ECONNRESET & 'socket hang up' — why connections reset and how to fix it

Quick answer: ECONNRESET ("read ECONNRESET" / "socket hang up") means the remote side closed the TCP connection abruptly while your app was using it. It's usually a reused keep-alive socket the server already dropped, an upstream that restarted mid-request, or a proxy idle-timeout. Make the client resilient: retry idempotent requests, and keep your client's idle timeout shorter than the server's.

Not your exact error? Paste it into the Deploy Error Decoder →
On this page

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

1

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.
2

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.
3

Compare the timeouts

# Server idle timeout must be >= client keep-alive timeout,
# or the client will keep grabbing sockets the server just closed.
The real fix

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.
How Infraveil handles this

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.

Connections drain on the old instance before it's stopped — fewer reset-on-deploy errors
Health-gated cutover means traffic only moves to a ready instance
Selected deploy events may be recorded; recovery controls are configured separately

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.

Free tools for this

Client-side, no signup — they run in your browser.