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@host hangs then fails with Control socket connect(/tmp/ssh-%r@%h:%p): Connection refused
  • ssh -v shows multiplexing: 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. 1.Identify stale control sockets:
  2. 2.```bash
  3. 3.# Find all SSH control sockets
  4. 4.find /tmp -name "ssh-*" -type s 2>/dev/null
  5. 5.# Check if master process is still running
  6. 6.ps aux | grep "ssh.*ControlMaster"
  7. 7.`
  8. 8.Remove stale socket files:
  9. 9.```bash
  10. 10.# Remove socket for a specific host
  11. 11.rm /tmp/ssh-user@host:22
  12. 12.# Or clean up all stale sockets
  13. 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. 14.`
  15. 15.Force a new master connection:
  16. 16.```bash
  17. 17.# Start a new master explicitly
  18. 18.ssh -o ControlMaster=yes -o ControlPath=/tmp/ssh-%r@%h:%p user@host
  19. 19.# Or force a non-multiplexed connection
  20. 20.ssh -o ControlMaster=no user@host
  21. 21.`
  22. 22.Configure automatic cleanup and timeouts:
  23. 23.```bash
  24. 24.# In ~/.ssh/config:
  25. 25.Host *
  26. 26.ControlMaster auto
  27. 27.ControlPath /tmp/ssh-%r@%h:%p
  28. 28.ControlPersist 600
  29. 29.# ControlPersist 600 means the master stays alive for 10 minutes
  30. 30.# after the last multiplexed session closes
  31. 31.`
  32. 32.Set up a cleanup cron job for stale sockets:
  33. 33.```bash
  34. 34.# Add to crontab
  35. 35.*/15 * * * * find /tmp -name "ssh-*" -type s -not -newer /tmp/.ssh-clean-marker -delete 2>/dev/null
  36. 36.touch /tmp/.ssh-clean-marker
  37. 37.`
  38. 38.Debug multiplexing issues with verbose output:
  39. 39.```bash
  40. 40.ssh -vvv -o ControlMaster=yes user@host
  41. 41.# Look for control socket creation and master process details
  42. 42.`

Prevention

  • Use ControlPersist with a reasonable timeout to automatically clean up idle masters
  • Store control sockets in a dedicated directory: ControlPath ~/.ssh/sockets/%r@%h:%p
  • Add ExitOnForwardFailure yes to 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