ERR_CONNECTION_RESET: Who killed the TCP handshake
Fix connection reset errors by identifying if the client, middlebox, or server sent the TCP RST packet.
Sandeep Sidhu · Founder, AlertKick
ERR_CONNECTION_RESET. The browser shows “This site can’t be reached - the connection was reset” and leaves you guessing. Something on the wire sent a TCP RST packet to tear the connection down: not a refusal, not a timeout, a slammed door.
The reset can come from the server itself, a middlebox like a firewall or load balancer, or occasionally the ISP. The browser cannot tell which. Diagnosis is about finding who sent the reset.
This error is frequently intermittent. A reset under load or at an idle-timeout boundary passes every manual retry. It is the classic “works when I test it” problem.
What ERR_CONNECTION_RESET actually means
Compare the connection behavior to its neighbours. ERR_CONNECTION_REFUSED is an instant rejection of the handshake because nothing is listening on the port. ERR_CONNECTION_TIMED_OUT is silence; the packet is dropped or lost in transit. A reset means a device actively killed the conversation after it had already started or during the handshake.
The TCP RST packet acts like a slammed door. The connection was opened, or at least attempted, and then forcibly torn down. This can happen mid-handshake or after data has started flowing. The device sending the RST decides the connection is no longer valid and drops the state.
You see this error in different forms depending on the tool. curl exits with code 56 and the message “Connection reset by peer”. Applications receive the ECONNRESET error code. These are the same event: a remote endpoint or intermediate device closed the socket abruptly.
The source of the RST is opaque to the client. A firewall might drop packets and send RSTs to speed up the client’s failure detection. An intrusion prevention system might reset connections that match a security rule. A load balancer might reset a connection if the backend worker crashes. An ISP might reset idle connections to free up resources. The browser receives the RST and displays the generic error page. It does not provide the IP address or hostname of the sender.
Diagnosis requires looking at the network path and the server logs. You must determine if the reset originated from the application server, a middlebox in the path, or the client’s own network. The next step is to isolate whether the problem is local to your machine or widespread.
Is the problem on your network or the server
Determine if the reset is isolated to your machine or affecting all users. This distinction separates local configuration issues from infrastructure failures.
Run AlertKick’s free website down checker. The tool executes the request from an external network without requiring a signup. It reports up/down status, HTTP response codes, redirect chains, and timing for DNS, TCP connect, TLS handshake, and first byte.
If the site loads correctly in the external checker but fails in your browser, the issue is visitor-side. The server is healthy; your local environment is injecting the reset. Common culprits include VPNs, proxies, or antivirus software that intercepts TLS traffic.
If the external checker also reports a reset or failure, the problem lies on the server side or in the network path between the checker and your server. The reset is originating from your infrastructure, a middlebox, or your ISP.
This initial triage prevents wasted time debugging local DNS or proxy settings when the server is actually down, or vice versa. Once you know the scope, you can proceed to the appropriate checklist.
Fix visitor-side resets
If the external checker confirms the site is reachable but you still see the error, the problem lives on your local machine or your immediate network path. The browser cannot tell you which device sent the reset, so you must isolate the variable.
Disable any VPN or proxy software. These tools terminate and re-open TCP connections, often injecting their own reset packets when they dislike the traffic pattern. If you use an antivirus suite with “web shield” or HTTPS scanning, disable that module temporarily. It intercepts TLS connections and resets them if it cannot verify the certificate chain.
Flush your local DNS cache. Stale records can point the browser to an old IP address that no longer serves the site, triggering a reset from the new infrastructure. Use the appropriate command for your OS:
- Windows:
ipconfig /flushdns - macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder - Linux (systemd-resolved):
sudo resolvectl flush-caches
Restart your router. Consumer NAT devices recycle their connection tables and can reset long-lived or new connections when the table fills up. A reboot clears the state and often resolves transient resets.
Test the site using a mobile phone on a cellular hotspot. If the error disappears on mobile data, the issue is specific to your home or office network, or the ISP path between your location and the server.
Check for MTU mismatches, which are common on PPPoE connections and some VPN configurations. Large packets get dropped mid-transfer, causing the connection to reset. Test this on Linux with:
ping -M do -s 1472 example.com
On macOS, use:
ping -D -s 1472 example.com
If you see “message too long” at packet sizes that should fit, your interface MTU is too high. Lower the MTU on your network adapter until the ping succeeds. This is a frequent cause of intermittent resets that pass manual retries but fail under real load.
Find the source of the RST packet
Reproduce the error from an external machine using verbose output. This reveals where the connection dies.
curl -v https://example.com
If the failure occurs during the TLS handshake, the issue likely points to TLS configuration or an interfering middlebox. If it fails after headers are received, the problem lies with the application or an idle-timeout boundary.
Catch resets on the wire directly on the server to see the direction of the packet.
sudo tcpdump -nn 'tcp[tcpflags] & (tcp-rst) != 0' -c 20
Resets originating from the server implicate the server stack. Resets arriving from outside implicate a middlebox or the client path.
Check for crashed or restarting workers. These processes reset their open connections immediately. Look for crash loops and out-of-memory kills.
journalctl -u <service> --since -1h
dmesg -T | grep -i -E 'oom|killed process'
The OOM killer ending a worker mid-response is a textbook source of ECONNRESET for whoever was connected.
Correlate reset reports with deploy timestamps. Deploys that restart the app or reload the proxy hard-close in-flight connections, causing immediate resets for active users.
Check for keepalive and idle-timeout mismatches behind a load balancer. If the application closes idle connections sooner than the load balancer expects, the balancer forwards a new request into a connection the app already closed. The client then sees a reset. Fix this by making the application’s keepalive timeout longer than the balancer’s idle timeout. In nginx, this involves setting keepalive_timeout for downstream connections and keepalive in the upstream block.
Verify TLS configurations. A listener without a certificate for the requested name, or a client speaking plain HTTP to an HTTPS port, will trigger an early reset. Confirm what the listener actually serves.
openssl s_client -connect example.com:443 -servername example.com </dev/null | head
Finally, check intrusion-prevention and DDoS layers. These security appliances send RSTs by design when a request matches a rule. Review the security appliance or WAF logs for the client IP before blaming the application.
Catch intermittent resets before users do
Resets tied to load spikes, idle-timeout boundaries, or a single network path will not show up in a quick manual test from your desk. You might retry the request ten times and see success every time, while your users are watching their browsers spin. This is the classic “works when I test it” scenario.
Scheduled checks from multiple geographic regions catch them. AlertKick monitors run from EU and US locations, recording exactly which phase failed: DNS lookup, TCP connect, TLS handshake, or first byte.
This granularity separates a broken app from a broken path. If the reset happens only in one region, the issue is likely your CDN, your ISP peering, or a regional firewall. If it happens everywhere, the problem is in your application or infrastructure.
Uptime monitors are included in the free plan. You can set up checks that alert by email, Slack, Telegram, or WhatsApp. Configure escalation chains so the right person sees the alert before the pager goes off for a problem that only affects 1% of your traffic.
If you suspect the issue is not a reset but a timeout, read the guide on connection timeouts.
Frequently asked questions
- What is the difference between ERR_CONNECTION_RESET, ERR_CONNECTION_REFUSED, and ERR_CONNECTION_TIMED_OUT?
- ERR_CONNECTION_RESET means a device actively killed the conversation by sending a TCP RST packet after the connection opened or during the handshake. ERR_CONNECTION_REFUSED is an instant rejection because nothing is listening on the port. ERR_CONNECTION_TIMED_OUT is silence where the packet is dropped or lost in transit.
- How can I tell if the connection reset is coming from my local network or the server?
- Run AlertKick's free checker at https://alertkick.com/tools/website-check to test the site from an external network. If the site loads externally but fails in your browser, the issue is visitor-side, such as a VPN or antivirus. If the external checker also reports a reset, the problem lies on the server side or in the network path.
- What commands should I use to flush DNS on Windows, macOS, and Linux?
- On Windows, run `ipconfig /flushdns`. On macOS, run `sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder`. On Linux with systemd-resolved, run `sudo resolvectl flush-caches`. Stale DNS records can point your browser to an old IP address that triggers a reset.
- How do I catch TCP RST packets on the server to identify the source?
- Run `sudo tcpdump -nn 'tcp[tcpflags] & (tcp-rst) != 0' -c 20` on the server to see the direction of the reset. Resets originating from the server implicate the server stack or application. Resets arriving from outside implicate a middlebox or the client path.
- Why does a keepalive timeout mismatch cause ERR_CONNECTION_RESET?
- If the application closes idle connections sooner than the load balancer expects, the balancer forwards a new request into a connection the app already closed. The client then sees a reset because the backend is no longer listening. Fix this by making the app's keepalive timeout longer than the balancer's idle timeout.
- How can I test for MTU mismatch issues causing resets?
- Test on Linux with `ping -M do -s 1472 example.com` or on macOS with `ping -D -s 1472 example.com`. If you see "message too long" at sizes that should fit, your interface MTU is too high. Lower the MTU on your network adapter until the ping succeeds.