ERR_CONNECTION_RESET / ECONNRESET (tested)

ERR_CONNECTION_RESET (Chrome) and ECONNRESET (Node.js) both mean the other side sent a TCP RST: it killed the connection instead of closing it politely. We triggered resets on purpose and wrote down what every client printed.

1. What a reset is

A TCP connection can end two ways. A FIN is a normal close: "I am done sending." A RST is an abort: "this connection is gone, drop everything." Clients report the two very differently. A reset can come from the server, or from anything in the middle: a proxy, a load balancer, a firewall, antivirus, or a VPN.

2. Our test server

We ran three tiny Node.js 24 servers on localhost. Each waits for the request bytes, then misbehaves:

const net = require('net');
function mk(port, fn) {
  net.createServer(s => { s.once('data', () => fn(s)); s.on('error', () => {}); })
     .listen(port, '127.0.0.1');
}
// A: RST before any response
mk(8993, s => s.resetAndDestroy());
// B: FIN before any response
mk(8994, s => s.destroy());
// C: headers + 1000 of 100000 body bytes, then RST
mk(8995, s => {
  s.write('HTTP/1.1 200 OK\r\nContent-Length: 100000\r\n\r\n' + 'x'.repeat(1000));
  setTimeout(() => s.resetAndDestroy(), 200);
});

socket.resetAndDestroy() sends a RST. socket.destroy() sends a FIN.

3. RST vs FIN before any response

ClientRST (resetAndDestroy)FIN (destroy)
Chromium 153 (page.goto)net::ERR_CONNECTION_RESETnet::ERR_EMPTY_RESPONSE
curl 8.14.1curl: (56) Recv failure: Connection reset by peercurl: (52) Empty reply from server
Node.js 24 fetchTypeError: fetch failed, cause ECONNRESET (read ECONNRESET)TypeError: fetch failed, cause UND_ERR_SOCKET (other side closed)
Python 3.13 urllibConnectionResetError: [Errno 104] Connection reset by peerRemoteDisconnected: Remote end closed connection without response

So the word "reset" only shows up for a real RST. If you see "empty reply" or "other side closed", the server closed cleanly without answering. That is a different bug, often a crash or a timeout in the app.

In Node.js, the useful part is in err.cause. The top-level message is just fetch failed in both cases. Log err.cause.code.

4. RST in the middle of the body

Server C sent a 200 status and headers, then 1000 of the promised 100000 bytes, then a RST.

ClientWhat happened
Chromium 153Request failed with net::ERR_CONNECTION_RESET. page.goto did not return a response: once it said Navigation ... is interrupted by another navigation to "chrome-error://chromewebdata/", once it timed out.
curl 8.14.1curl: (56) Recv failure: Connection reset by peer (same code as before headers)
Node.js 24 fetchfetch() resolved with status 200. Reading the body threw TypeError: terminated, cause ECONNRESET.
Python 3.13 urlliburlopen() returned status 200. read() raised ConnectionResetError: [Errno 104] Connection reset by peer.

The trap: in Node.js and Python, the status check passes. The error only appears when you read the body. Wrap the body read in your error handling and retry logic, not just the request.

5. The classic Node.js cause: keep-alive race

A very common ECONNRESET in Node.js services comes from connection reuse. The server closes an idle keep-alive connection at the same moment the client sends a new request on it. The client gets a reset or a closed socket. The fix is to make the server's idle timeout longer than the client's (or the load balancer's). We measured this in the Keep-Alive and Connection header guide. If a proxy sits between them, the same race shows up as a 502 Bad Gateway.

6. Server closing on a too-large request

Some servers and proxies give up on a request that is too big and close the connection instead of sending a full error response. Then the client sees a reset where you expected a status code. Check request size limits: see 431 Request Header Fields Too Large for big headers or cookies, and 413 Request Entity Too Large for big uploads.

7. Causes outside your code (not tested)

These come from vendor docs and common troubleshooting, not from our run:

8. How to narrow it down

  1. Run curl -v against the same URL. Exit 56 means reset; exit 52 means clean close with no reply.
  2. Try from another network. If the error goes away, look at the network path, not the server.
  3. Hit the server directly, skipping the proxy or CDN. If that works, the proxy is the one resetting.
  4. Check server logs at the exact time. A crash, a timeout, or a size limit usually shows up there.

Frequently asked questions

What is the difference between ERR_CONNECTION_RESET and ERR_EMPTY_RESPONSE?

In our test, Chromium showed ERR_CONNECTION_RESET when the server sent a TCP RST, and ERR_EMPTY_RESPONSE when the server closed normally (FIN) without sending anything. curl showed exit 56 and exit 52 for the same two cases.

Why does Node.js fetch just say 'fetch failed'?

The real reason is in err.cause. For a reset we saw cause code ECONNRESET with message 'read ECONNRESET'. For a clean close it was UND_ERR_SOCKET with 'other side closed'. Log err.cause.code.

Can I get a 200 status and still get ECONNRESET?

Yes. When the server reset after sending headers, Node.js fetch and Python urllib both returned status 200. The error came only when reading the body: 'TypeError: terminated' (cause ECONNRESET) in Node.js and ConnectionResetError in Python.

What is the most common cause of ECONNRESET in Node.js servers?

A keep-alive race: the server closes an idle connection just as the client reuses it. Make the server's keepAliveTimeout longer than the client's or load balancer's idle timeout. See our Keep-Alive guide.

Does netsh winsock reset fix ERR_CONNECTION_RESET?

Sometimes, on Windows, when other software has changed network settings. We did not test it. Try it after ruling out antivirus, VPN and proxy, and after checking the site works from another device.

Written with AI assistance. Measured on 2026-10-02 with headless Chromium 153 (Playwright 1.63), curl 8.14.1, Node.js 24.21.0 fetch and Python 3.13.5 urllib against a tiny Node.js server that sent a TCP RST (socket.resetAndDestroy()) or a plain FIN (socket.destroy()). PlainHeaders is our extension; Chromium, curl, Node.js and Python are free.