ERR_CONNECTION_RESET (Chrome): what it means and how to fix it
The browser opened a connection — then the other side (or something in the middle) aborted it with a TCP reset. You get a “connection was reset” failure instead of a web page.
What you see
This site can’t be reached
The connection was reset.
ERR_CONNECTION_RESET
# Firefox often:
The connection to the server was reset while the page was loading.
# curl may say:
curl: (56) Recv failure: Connection reset by peer
# or: curl: (35) OpenSSL SSL_connect: Connection reset by peer
Safari / Edge use similar “connection reset” wording. Same idea: an abrupt TCP abort, not a normal HTTP error page.
Reset vs empty vs closed vs refused
| Symptom | What happened on the wire | Typical cause |
|---|---|---|
| ERR_CONNECTION_RESET | TCP RST — peer aborted | Firewall RST, middlebox, process crash, proxy kill |
| ERR_EMPTY_RESPONSE | Connected; 0 HTTP bytes; then close | Crash after accept, protocol mismatch |
| ERR_CONNECTION_CLOSED | FIN without a complete response | Idle timeout, graceful half-close |
| ERR_CONNECTION_REFUSED | Nothing accepted TCP | No listener — never a mid-stream reset |
| ERR_CONNECTION_TIMED_OUT | No useful reply in time | DROP firewall, blackhole (often no RST) |
| ECONNRESET (Node) | Same RST family in server-side clients | Upstream/proxy aborted the Node socket |
| Cloudflare 520 | CF got empty/invalid origin reply | Origin-side cousin; visitors may see CF branding instead |
Rule of thumb: reset = “someone sent RST.” Refused = “nobody listened.” Empty = “listened, then gave zero HTTP.” Timeout = “silence long enough that the client gave up.”
Frequent real causes
- Host firewall / security group RST — port looks open from one path, RST from another (asymmetric rules, fail2ban, cloud SG).
- TLS inspection / antivirus / corporate proxy — middlebox accepts then aborts when it dislikes the handshake or destination.
- Load balancer / reverse proxy idle kill — upstream closed; proxy resets the client socket instead of returning a clean 502/504.
- Process crash under load — worker dies; kernel RSTs accepted connections (OOM 137 is a frequent trigger).
- HTTP/2 or TLS version fights — rare, but broken middleboxes RST when ALPN/HTTP2 disagrees; try
curl --http1.1. - Wrong service on the port — something accepts then immediately resets non-native protocols.
Diagnose in a few commands
# Verbose client view
curl -v --max-time 15 https://example.com/ -o /dev/null
# Force HTTP/1.1 in case h2 middleboxes RST
curl -v --http1.1 --max-time 15 https://example.com/ -o /dev/null
# Compare TCP reachability (no HTTP yet)
nc -vz example.com 443
# or: timeout 5 bash -c 'echo >/dev/tcp/example.com/443' && echo open
# On the server (Linux): who listens, any firewall counters?
sudo ss -lptn 'sport = :443'
sudo journalctl -u nginx -u your-app --since "10 min ago" | tail
- Reproduce with
curl -v. Note whether RST happens during TCP, during TLS, or after HTTP request bytes. - Try another network (phone tether vs office Wi-Fi) to spot middleboxes.
- From the server, curl localhost and the public IP. Local OK + public RST ⇒ firewall / edge path.
- Check proxy timeouts and upstream health if a load balancer sits in front.
- Watch for OOM / crash logs at the same second as the Ray ID or access log gap.
Fixes that usually work
- Open / correct the firewall path so allowed clients get ACCEPT, not REJECT/RST, on the HTTPS port.
- Align proxy idle timeouts with the app; return a deliberate 502/504 instead of killing sockets blindly.
- Fix the crashing worker (memory limits, panic logs) so accepted connections can finish headers.
- For corporate devices, test outside the inspecting proxy; ask IT for a TLS-bypass for the destination if appropriate.
- If only HTTP/2 clients fail, temporarily prefer HTTP/1.1 at the edge while you fix the middlebox or ALPN config.
Related
ERR_EMPTY_RESPONSE · ECONNRESET / read ECONNRESET · ERR_CONNECTION_TIMED_OUT · localhost refused to connect · Cloudflare Error 520 · 502 Bad Gateway · exit code 137 / OOM · Anvil HTTP status · Wirebook busy-servers lesson
Questions
What does ERR_CONNECTION_RESET mean?
The browser’s TCP connection was aborted with a reset (RST) before a usable HTTP response finished — Chrome shows net::ERR_CONNECTION_RESET.
How is reset different from ERR_EMPTY_RESPONSE?
Reset is an abrupt RST. Empty response usually means the connection closed after connect with zero HTTP bytes, often without a RST.
How is this different from connection refused?
Refused means nothing accepted the TCP handshake. Reset means something accepted (or a middlebox engaged) and then aborted the session.
Is this the same as Node’s ECONNRESET?
Same family of TCP abort. Browsers say ERR_CONNECTION_RESET; Node client errors often say ECONNRESET or read ECONNRESET.
Can a firewall cause ERR_CONNECTION_RESET?
Yes. REJECT rules and many network firewalls send RST. DROP rules more often look like a timeout instead.
Can antivirus TLS inspection cause it?
Yes. Intercepting proxies that fail during handshake frequently reset the client connection. Compare on another network.
What should I try first with curl?
curl -v, then curl -v --http1.1, and compare from another network. Note whether the RST is during TCP, TLS, or after the HTTP request.
Published .