Introduction
SSH connection multiplexing (ControlMaster/ControlPath) allows multiple SSH sessions to a single host to share one TCP connection, significantly speeding up subsequent connections. However, when the master connection dies (network interruption, server reboot, timeout), the control socket file remains on disk. New connections attempt to use the stale socket and fail with muxserver_listen bind: No such file or directory or Control socket connect failed.
Symptoms
ssh user@hosthangs then fails withControl socket connect(/tmp/ssh-%r@%h:%p): Connection refusedssh -vshowsmultiplexing: control socket connected, but master is gone- Stale socket file exists but the master process has exited
- New connections fail while existing multiplexed sessions still work
ls -la /tmp/ssh-*shows socket files for disconnected hosts
Common Causes
- Master connection terminated by network interruption or server reboot
- Control socket file not cleaned up after master exits
- ControlPersist timeout expired but socket file not removed
- Multiple users sharing the same ControlPath template causing conflicts
- Filesystem cleanup removed the socket file while master is still running
Step-by-Step Fix
- 1.Identify stale control sockets:
- 2.```bash
- 3.# Find all SSH control sockets
- 4.find /tmp -name "ssh-*" -type s 2>/dev/null
- 5.# Check if master process is still running
- 6.ps aux | grep "ssh.*ControlMaster"
- 7.
` - 8.Remove stale socket files:
- 9.```bash
- 10.# Remove socket for a specific host
- 11.rm /tmp/ssh-user@host:22
- 12.# Or clean up all stale sockets
- 13.find /tmp -name "ssh-*" -type s -exec test ! -e /proc/$(ss -tlnp | grep {} | awk '{print $NF}' | grep -oP 'pid=\K\d+')/fd/0 \; -delete 2>/dev/null
- 14.
` - 15.Force a new master connection:
- 16.```bash
- 17.# Start a new master explicitly
- 18.ssh -o ControlMaster=yes -o ControlPath=/tmp/ssh-%r@%h:%p user@host
- 19.# Or force a non-multiplexed connection
- 20.ssh -o ControlMaster=no user@host
- 21.
` - 22.Configure automatic cleanup and timeouts:
- 23.```bash
- 24.# In ~/.ssh/config:
- 25.Host *
- 26.ControlMaster auto
- 27.ControlPath /tmp/ssh-%r@%h:%p
- 28.ControlPersist 600
- 29.# ControlPersist 600 means the master stays alive for 10 minutes
- 30.# after the last multiplexed session closes
- 31.
` - 32.Set up a cleanup cron job for stale sockets:
- 33.```bash
- 34.# Add to crontab
- 35.*/15 * * * * find /tmp -name "ssh-*" -type s -not -newer /tmp/.ssh-clean-marker -delete 2>/dev/null
- 36.touch /tmp/.ssh-clean-marker
- 37.
` - 38.Debug multiplexing issues with verbose output:
- 39.```bash
- 40.ssh -vvv -o ControlMaster=yes user@host
- 41.# Look for control socket creation and master process details
- 42.
`
Prevention
- Use
ControlPersistwith a reasonable timeout to automatically clean up idle masters - Store control sockets in a dedicated directory:
ControlPath ~/.ssh/sockets/%r@%h:%p - Add
ExitOnForwardFailure yesto ensure master exits cleanly when forwarding fails - Monitor SSH multiplexing health in long-running CI/CD or deployment pipelines
- Use unique ControlPath templates per user to avoid cross-user conflicts