VPS Tutorials
VPS SSH Keeps Disconnecting (2026): Troubleshooting Broken pipe, Connection reset, Idle Timeout and Network Jitter
After you connect to a VPS over SSH, the session drops after a while, or you see Broken pipe, Connection reset by peer, or Operation timed out. This is usually not a wrong password but idle timeout, network jitter, NAT reclamation, sshd keepalive, or a local network problem. This article gives troubleshooting and fix commands across three layers: client, server, and network path.

VPS SSH Keeps Disconnecting (2026): Troubleshooting Broken pipe, Connection reset, Idle Timeout and Network Jitter
SSH connects, but drops after a while. That is more annoying than not connecting at all.
The common errors are roughly these:
client_loop: send disconnect: Broken pipe
packet_write_wait: Connection to x.x.x.x port 22: Broken pipe
Connection reset by peer
Connection closed by remote host
Operation timed out
These problems are not the same as Permission denied. Permission denied means authentication failed; Broken pipe and Connection reset usually mean the connection was established but was cut off mid-way by some layer.
Many places can cut your connection: your local network, company/campus NAT, router, inter-provincial links, cloud provider security policies, the VPS's sshd configuration, system resource pressure, or even your terminal sitting idle for a long time.
This article is ordered by practicality: first stop SSH from dropping when idle, then determine whether the problem is the VPS or the network path.
First see which case you are in:
| Symptom | More likely direction |
|---|---|
Permission denied immediately on connect | User, key, permissions, sshd configuration |
Connection timed out immediately on connect | Firewall, security group, port, network path |
| Connects, then drops after a few minutes of inactivity | Idle timeout, NAT reclamation, keepalive |
| Drops even while running commands | Network jitter, VPS load, sshd restarted |
| More likely to drop during evening peak | Link congestion, packet loss, poor return path quality |
If you get authentication failure immediately on connect, see: VPS SSH Permission denied: what to do.
If you cannot connect at all after enabling the firewall, see: VPS SSH unreachable after enabling UFW: what to do.
The rest of this article mainly handles "connects but drops mid-session".
The most common case: you leave the SSH window idle for a few minutes, come back, press a key, and it drops.
This is usually because an intermediate network device considers the connection idle and reclaims the TCP session. Home routers, company gateways, carrier NAT, and mobile hotspots can all do this.
First add this to your local computer's SSH configuration:
mkdir -p ~/.ssh
nano ~/.ssh/config
Write:
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
The meaning is simple: the client sends a keepalive packet to the server every 30 seconds; only after 3 consecutive non-responses does it consider the connection dead.
Save and reconnect:
ssh root@your_server_ip
If you use a custom port:
ssh -p 2222 root@your_server_ip
If your previous symptom was "drops after being idle for a while", this step alone usually improves things noticeably.
If you don't want to change the config first, you can temporarily add parameters to test:
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 root@your_server_ip
If the connection is stable this way, then write it into ~/.ssh/config.
You can also make it apply to only one VPS:
Host my-vps
HostName your_server_ip
User root
Port 22
ServerAliveInterval 30
ServerAliveCountMax 3
Connect later with:
ssh my-vps
This is less hassle than typing parameters each time and less easy to forget.
When client keepalive is not enough, look at the VPS server-side configuration.
Open the sshd configuration:
sudo nano /etc/ssh/sshd_config
Confirm or add:
ClientAliveInterval 60
ClientAliveCountMax 3
TCPKeepAlive yes
Then first test whether the configuration has syntax errors:
sudo sshd -t
No output usually means it is fine. Then reload SSH:
sudo systemctl reload ssh
On some systems the service is named sshd:
sudo systemctl reload sshd
Don't reboot the machine right away. First sshd -t, then reload. A wrong sshd configuration can lock you out, especially when you have no console.
If the disconnect is not due to idleness, server logs will give clues.
Ubuntu / Debian:
sudo journalctl -u ssh --since "1 hour ago"
sudo tail -n 100 /var/log/auth.log
CentOS / Rocky / AlmaLinux:
sudo journalctl -u sshd --since "1 hour ago"
sudo tail -n 100 /var/log/secure
Focus on these keywords:
sudo journalctl -u ssh --since "1 hour ago" | grep -Ei "disconnect|reset|timeout|error|kex|fatal|oom"
If you can see Received disconnect in the logs, the server knows the connection was cut.
If there is no corresponding record in the logs at all, but the client directly gets Broken pipe, it is more like the intermediate network broke, or the local link is unstable.
Client debug information is very useful:
ssh -vvv root@your_server_ip
Around the disconnect, focus on:
debug1: client_input_channel_req: channel 0 rtype [email protected]
packet_write_wait: Connection to x.x.x.x port 22: Broken pipe
Connection reset by peer
If keepalive repeatedly gets no response before the disconnect, the client sends packets but gets no reply from the server. At this point don't rush to change sshd; test network packet loss first.
On your local computer, test:
ping your_server_ip
Watch for 1-2 minutes to see whether there is packet loss or a sudden latency spike.
Using mtr is more recommended:
mtr -rw your_server_ip
If you don't have mtr locally, macOS can install it with Homebrew, and Linux can install it with the package manager:
sudo apt install mtr-tiny
When reading results, don't stare only at the last hop. Packet loss at one intermediate hop does not necessarily indicate a problem; the key is whether the last few hops have sustained packet loss and whether latency rises regularly.
If it only drops in the evening and rarely during the day, you can also read: Why VPS gets slow at evening peak. SSH disconnects are sometimes not a configuration problem but evening-peak jitter on the network path.
If the VPS has heavy CPU, memory, or disk I/O pressure, SSH sessions can also stall or even drop. This is especially true on low-spec machines running Docker, databases, backup compression, or log writes.
After logging in, run:
uptime
free -h
df -h
View real-time processes:
top
If you have htop it is more intuitive:
sudo apt install htop
htop
Check whether the system has OOM or disk errors:
dmesg -T | grep -Ei "oom|killed process|i/o error|reset|ext4|nvme"
If the machine was already clearly sluggish before SSH dropped, and command input was also delayed, the problem may not be SSH but the VPS itself under too much pressure.
If every disconnect happens at a fixed time, such as every day at dawn, it may be affected by service reload, automatic updates, panel tasks, or log rotation.
Check the recent status of the ssh service:
sudo systemctl status ssh
sudo journalctl -u ssh --since "24 hours ago"
On CentOS-family systems:
sudo systemctl status sshd
sudo journalctl -u sshd --since "24 hours ago"
If you see sshd restarting frequently, keep investigating what triggers it:
sudo journalctl --since "24 hours ago" | grep -Ei "ssh|sshd|restart|reload|apt|dnf|yum|unattended"
Automatic updates generally should not frequently drop SSH, but if system package upgrades, configuration management tools, or panels are modifying sshd, be careful.
Even if you fix keepalive, it is not recommended to run long tasks directly in a bare SSH session. The network will always fluctuate.
Install tmux:
sudo apt update
sudo apt install tmux
Create a new session:
tmux new -s work
Run tasks inside it. Temporarily detach without ending the task:
Ctrl+b 然后按 d
Come back next time:
tmux attach -t work
If you are running compilation, backups, migrations, or database imports, tmux is far more reliable than praying SSH won't drop.
If you often use mobile hotspots, airport networks, or cross-border links, SSH is not friendly to IP switching and weak networks. mosh is more resistant to jitter.
Install on the server:
sudo apt install mosh
Install mosh locally too, then connect:
mosh root@your_server_ip
Note: mosh needs UDP ports, and the default range is usually 60000-61000/udp. If you enabled UFW or a cloud firewall, you need to allow them:
sudo ufw allow 60000:61000/udp
If you only manage VPSs normally, configuring SSH keepalive and tmux is enough; mosh is better for weak networks and mobile scenarios.
Local ~/.ssh/config:
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
TCPKeepAlive yes
Server-side /etc/ssh/sshd_config:
ClientAliveInterval 60
ClientAliveCountMax 3
TCPKeepAlive yes
After changing the server side, remember:
sudo sshd -t
sudo systemctl reload ssh
If the service name is wrong, then use:
sudo systemctl reload sshd
A simple way to judge:
- Only SSH drops; website, ping, and mtr are all normal: look at keepalive and sshd first
- SSH, website, and database connections all jitter together: look at VPS load or the network path first
- Only drops in a certain network environment: look at the local network, company gateway, or mobile hotspot first
- Only drops at evening peak: look at link congestion and packet loss first
- Cannot connect at all: look at firewall, security group, port, and authentication first
SSH is just the first place the problem shows up; it is not necessarily the real root cause.
- VPS unreachable? SSH login troubleshooting: if you cannot connect at all now, start with ports and firewall.
- VPS SSH Permission denied: what to do: if it is authentication failure, focus on keys, users, and permissions.
- VPS SSH unreachable after enabling UFW: what to do: if SSH broke right after enabling the firewall, handle UFW first.
- Why VPS gets slow at evening peak: if SSH disconnects have an obvious time window, troubleshoot the network path and host resources.
Finally, a practical suggestion: as long as you log in to VPSs often, configure ServerAliveInterval and tmux. The former reduces idle disconnects; the latter ensures tasks survive after a disconnect. SSH connections can drop; tasks should not drop with them.