SOPs
Mosh — Resilient SSH
The rule
Section titled “The rule”Use mosh for interactive terminal sessions across my machines. Use ssh for everything non-interactive (scripts, one-shot commands, rsync, git).
Mosh where drops hurt, SSH where scripting matters.
Install
Section titled “Install”brew install moshVersion 1.4.0 as of 2026-04-24. Both ends need it, the local machine and the remote.
Installed on: MacBook Pro, Mac Studio. Not yet on: Remote Mac, VPS.
mosh studio # → Mac Studiomosh mbp # → MacBook ProSSH aliases in ~/.ssh/config resolve the same way they do for ssh. The terminal title shows something like mosh-client -# studio | 192.168.1.220 60001 when the session is live. The trailing number is the UDP port mosh bound to.
How it works
Section titled “How it works”- Mosh SSHes in to launch
mosh-serveron the remote and receive a one-time key plus a UDP port. - The session then switches to UDP (ports 60000 to 61000) using that key.
- UDP survives IP changes, sleep, and Wi-Fi flips. SSH does not.
The SSH bootstrap is where the tricky behavior lives. Non-interactive SSH shells on macOS behave differently from interactive ones, which leads directly to the gotcha below.
The .zshenv PATH gotcha
Section titled “The .zshenv PATH gotcha”Symptom. First mosh studio from MacBook Pro returned:
zsh:1: command not found: mosh-server/opt/homebrew/bin/mosh: Did not find mosh server startup message.Cause. Mosh’s SSH bootstrap runs a non-interactive, non-login zsh on the remote. That shell does not source .zshrc or .zprofile, which is where Homebrew’s PATH export normally lives. So mosh-server at /opt/homebrew/bin/mosh-server is not on PATH, the bootstrap fails, and mosh reports “did not find startup message.”
Fix. Write a one-line ~/.zshenv on every machine mosh reaches:
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:$PATH".zshenv is the only zsh init file that loads for every invocation: interactive, non-interactive, login, non-login. It is the right hook for anything an SSH-bootstrapped tool needs on PATH.
Firewall
Section titled “Firewall”Mosh uses UDP 60000 to 61000. On both the MacBook Pro and Mac Studio the macOS Application Firewall is disabled (socketfilterfw --getglobalstate reports “Firewall is disabled”), so nothing to configure. If a firewall ever gets enabled, either allow mosh-server as an app or open UDP 60000 to 61000.
Precedent
Section titled “Precedent”2026-04-24. VS Code Remote SSH sessions from MacBook Pro into Mac Studio were dying with Claude Code process exited with code 143 (SIGTERM). Root cause was SSH ControlMaster tearing down on brief network blips and taking the remote shell, plus the Claude Code process, with it. Installed mosh on both ends to eliminate the wobble. First launch hit the .zshenv PATH gotcha above. Fixed, retested, documented here.
How to update this page
Section titled “How to update this page”- New machine joins the fleet →
brew install mosh, write.zshenv, add a line under “Installed on” in the Install section. - Firewall state changes on any machine → update the Firewall section.
- Future mosh versions change behavior → update the Install section and add a line under Precedent.
Related
Section titled “Related”- Local reference with a shorter version:
~/apps/cc/infrastructure-guide.md - Mosh homepage