Fixing VS Code Remote-SSH Connection Drops and "Could Not Establish Connection" Errors
A Remote-SSH session in VS Code works fine for a while, then drops — and reconnecting fails with "Could not establish connection to [host]." A plain terminal SSH to the same host still works perfectly, which means the network is fine; something about the VS Code Server's persistent connection and background process on the remote host is what actually broke.
The Problem
A VS Code Remote-SSH session connects and works normally, then at some point — after the laptop sleeps, a network switch (Wi-Fi to VPN, office to home), or just a long idle period — the connection drops. Reopening the folder or reconnecting fails with Could not establish connection to "[host]", sometimes with no further detail. Running ssh user@host directly from a regular terminal at the same moment connects instantly and works fine, which rules out the SSH credentials, the network path, and the remote host being down.
Why It Happens
An idle TCP connection gets silently dropped by something in the network path, and neither end notices
Corporate firewalls, NAT gateways, and some VPNs silently close TCP connections that have been idle past a certain timeout, without sending either endpoint a proper close signal. Without SSH-level keepalive packets, both the local VS Code client and the remote SSH session can be sitting on a connection that's already dead from the network's perspective, and neither side finds out until the next attempted read or write simply hangs or times out.
The VS Code Server process on the remote host gets killed independently of the SSH connection itself
VS Code's Remote-SSH extension works by installing and running a persistent server process (vscode-server) on the remote machine, separate from the SSH transport itself. That process can be killed by the remote host's OOM killer under memory pressure, cleaned up by a session-timeout policy on shared servers, or simply left in a broken state after an interrupted install — and when it's gone, reconnecting the SSH transport alone doesn't help, because there's no server process left for the client to actually attach to.
A version mismatch between the local VS Code client and the installed remote server
After a local VS Code update, the client expects a specific server version on the remote host. If the previously installed vscode-server version doesn't match and the automatic update/reinstall step fails partway (a flaky connection during that specific step is a common trigger), the remote host is left with a partially installed or incompatible server binary that neither the old nor new client version can properly attach to.
The Fix
1. Add SSH keepalive settings so dead connections are detected quickly instead of hanging silently
# ~/.ssh/config
Host myserver
HostName example.com
User deploy
ServerAliveInterval 30
ServerAliveCountMax 3
ServerAliveInterval makes the SSH client send a keepalive probe every 30 seconds of inactivity; ServerAliveCountMax gives up and closes the connection after 3 missed responses. This both prevents idle-timeout drops from intermediate network equipment and, when a connection genuinely does die, surfaces the failure quickly instead of leaving VS Code hung on a connection that's already gone.
2. Clear the remote VS Code Server installation to force a clean reinstall
# run on the remote host, over a plain SSH session
rm -rf ~/.vscode-server
This removes any partially installed, version-mismatched, or otherwise corrupted server binary, forcing VS Code to perform a completely fresh install on the next connection attempt — the most reliable fix for a version-mismatch or interrupted-install state that a normal reconnect can't repair on its own.
3. Check whether the remote host's OOM killer or a session policy is actually killing the server process
# on the remote host
dmesg | grep -i "killed process" | grep -i vscode
journalctl --since "1 hour ago" | grep -i oom
If the vscode-server process is being killed for memory pressure (common on small remote VMs) or a shared server's idle-session cleanup policy, the connection dropping is a symptom of that, not a VS Code bug — the actual fix is either increasing available memory/swap on the remote host or requesting an exemption from whatever session-cleanup policy is terminating the process.
4. Disable SSH connection multiplexing (ControlMaster) if it's configured and causing stuck sockets
# ~/.ssh/config
Host myserver
ControlMaster no
ControlMaster multiplexing reuses a single underlying TCP connection across multiple SSH sessions for speed, but a stuck or half-dead multiplexed socket can silently break every session sharing it, including VS Code's — disabling it isolates each connection attempt, trading a small amount of connection speed for eliminating a whole class of shared-socket failures.
Why This Works
Each fix addresses a distinct failure mode that all present the same way to VS Code: keepalive settings close the gap where a network device silently drops an idle connection neither endpoint would otherwise notice; clearing the server install closes the gap where the remote server binary itself is broken or mismatched, independent of the SSH transport; checking for OOM kills or session policies identifies when the server process is being terminated by something outside VS Code's control entirely; and disabling connection multiplexing removes a shared-failure point that can silently affect an otherwise-healthy connection.
Conclusion
A VS Code Remote-SSH connection that drops and won't reconnect is almost never a problem with the SSH credentials or network path itself — those already work if a plain terminal SSH succeeds. Add SSH keepalive settings to detect dead connections quickly, clear ~/.vscode-server on the remote host to force a clean server reinstall after a version mismatch, check the remote host's logs for the server process being killed by OOM or a session policy, and disable SSH connection multiplexing if it's in use and implicated.
