Troubleshooting
Connection failures, UDP firewalls, locked keychains, missing pushes, CJK locale fixes, dictation problems, and hook diagnostics.
SSH cannot connect
Check the basics from another machine first:
$ssh user@host -p 22
If plain SSH fails outside Moshi, fix host reachability, username, port, firewall, DNS, VPN, or credentials first.
Mosh cannot connect
Mosh needs SSH for startup and UDP for the live session. If SSH works but mosh does not:
- Confirm
mosh-serverexists on the host. - Open UDP
60000:61000or the custom range you configured. - Check whether the current network blocks UDP.
- Try connection type SSH as a fallback.
- Set a custom mosh path if
mosh-serveris installed outside PATH.
mosh-server is installed but not found
Mosh bootstraps through a non-interactive SSH session, which does not load ~/.zshrc, ~/.bashrc (interactive section), or ~/.profile. A Homebrew-installed mosh-server (/opt/homebrew/bin on Apple Silicon, /usr/local/bin on Intel/Linuxbrew) often isn't on the non-interactive PATH.
Two fixes:
- Add the path to a file the non-interactive shell does load:
# zsh: ~/.zshenv# bash: top of ~/.bashrc, before any interactive guard$export PATH="/opt/homebrew/bin:$PATH"
- Or set Mosh path in the connection's Mosh options to the absolute path:
$/opt/homebrew/bin/mosh-server$/usr/local/bin/mosh-server
Tailscale connections
For Tailscale-specific issues — wrong address, "unable to authorize", OS Error 4, Mac sleep behavior — see Tailscale.
Jump host fails
Jump hosts are available for SSH connections. If you configured a jump host while forcing mosh, switch the connection type to SSH or connect through a network path where the final host is directly reachable.
Key import fails
Moshi expects a private key. Public keys starting with ssh-rsa, ssh-ed25519, ecdsa-sha2-*, or PEM public-key blocks are rejected in the private-key field.
If a private key has a passphrase, enter the passphrase in the connection form.
moshi-hook install download fails (403 / Cloudflare challenge)
The install.sh script and brew install moshi-hook both pull binaries from cdn.getmoshi.app (Cloudflare). On rare networks Cloudflare's bot protection serves a JS challenge to curl, which returns HTTP 403 with a cf-mitigated: challenge header.
Confirm the challenge is what you're hitting:
$curl -v https://cdn.getmoshi.app/hook/v0.1.4/moshi-hook_Linux_x86_64.tar.gz 2>&1 | head -30
If the response includes HTTP/2 403 and cf-mitigated: challenge, no curl flag will get past it — the challenge requires a real browser to solve.
Manual install:
- Open the URL printed by the install script in a browser. The browser solves the challenge and downloads the tarball.
- Move the file onto the host (scp, USB, AirDrop, etc.).
- Extract and place the binary on PATH:
$tar -xzf moshi-hook_Linux_x86_64.tar.gz$sudo mv moshi-hook /usr/local/bin/$moshi-hook pair --token <token>$moshi-hook install
If you hit this from a region or PoP that consistently challenges, send a curl -v capture to Settings -> Support so the CDN rule can be tuned.
macOS Keychain blocks moshi-hook
If pairing from SSH or a locked macOS session fails, unlock the login keychain:
$security unlock-keychain ~/Library/Keychains/login.keychain-db$moshi-hook pair --token <token>
For headless use, pair with file storage:
$moshi-hook pair --token <token> --store file
tmux is installed but Moshi doesn't detect it
Moshi detects tmux over a non-interactive SSH session, which often skips ~/.bashrc, ~/.profile, and ~/.zshrc. If tmux lives in a directory those rc files add to PATH (for example /usr/local/bin or /opt/homebrew/bin), the non-interactive shell won't see it.
Check what the SSH session actually sees:
$ssh <host> 'echo PATH=$PATH; command -v tmux'
If command -v tmux prints nothing, either symlink tmux into a directory already on PATH or extend the non-interactive PATH in ~/.zshenv (zsh) or the top of ~/.bashrc before any interactive guard (bash). See tmux for setup.
moshi-hook is installed but shows as not installed
A hollow-grey not installed dot means Moshi's host check could not resolve the moshi-hook binary. That check runs over a non-interactive login SSH shell and searches the standard install locations — ~/.local/bin, ~/bin, /opt/homebrew/bin, /usr/local/bin, /opt/local/bin — before your login shell's own PATH (from /etc/profile and ~/.profile, not ~/.bashrc, ~/.zshrc, or fish config). A Homebrew or default install.sh install lives in one of those directories and is detected automatically.
You only hit a false not installed when moshi-hook sits in a custom directory — for example installed with INSTALL_DIR=/some/where — that is neither one of those standard paths nor on the login-shell PATH.
Confirm what a login shell resolves. A plain ssh <host> 'command -v moshi-hook' skips the login shell and the standard search paths, so it is not representative:
$ssh <host> 'sh -lc "command -v moshi-hook"'
If that prints nothing, either symlink the binary onto a standard path:
$sudo ln -sfn /custom/dir/moshi-hook /usr/local/bin/moshi-hook
or add its directory to ~/.profile so the login shell exports it:
$echo 'export PATH="/custom/dir:$PATH"' >> ~/.profile
The other dot colors are not PATH problems: not running (solid grey) means start the daemon, wrong port (red) means the gateway isn't on 127.0.0.1:24543, and update (amber) means upgrade moshi-hook. See Host status dot for each.
Agent events do not appear
Run:
$moshi-hook status$moshi-hook logs -f$moshi-hook install
Confirm the daemon is running, the host is paired with the token from your Moshi app, and the agent you are using is one of the supported installers.
Push notifications do not arrive
- Confirm iOS notification permission is enabled for Moshi.
- Confirm notifications are not paused in Moshi settings.
- Send a test notification from the settings screen.
- On simulator, test push delivery is not representative of a real device.
- For agent events, confirm
moshi-hook serveor the macOS service is running.
Diff or browser preview is unavailable
Both features rely on the local gateway WebSocket that moshi-hook exposes. If the iOS app shows "Diff unavailable" or no dev servers appear under browser preview, walk through Debugging the gateway WebSocket to confirm the daemon is running, the session lookup resolves, and the SSH tunnel is still in place.
Live Activity does not update
Check Settings -> Agent Hooks:
- Live Activity toggle is enabled.
- The demo Live Activity can start.
- Agent events are reaching the inbox.
Live Activities depend on iOS support and system policy. If the inbox updates but the Live Activity does not, restart the app and test with the demo action.
Pro is not recognized on a new device
A Pro purchase (subscription or lifetime) is tied to your Apple ID and works on every device signed in to the same Apple ID. After installing Moshi on a new device, open Settings -> Pro and tap Restore.
If Restore does nothing, confirm the device is signed in with the Apple ID that made the purchase. Restore brings back entitlements only — to also bring saved connections, enable iCloud sync in Moshi settings on both devices.
Korean or CJK characters do not render
The remote shell needs a UTF-8 locale for CJK output to render. Confirm with locale on the host; if it shows C or POSIX, set LANG=en_US.UTF-8 (or the equivalent for your locale) in ~/.zshenv or the non-interactive section of ~/.bashrc. See CJK and IME input for the full setup.
Dictation quality is poor
- Try a different Whisper model.
- Pin the language instead of using automatic detection.
- Use chat mode for natural-language agent prompts.
- Turn off auto-send while testing so you can edit before submission.
Need help
Use Settings -> Support to email support with the host OS, connection type, Moshi version, and the exact error shown in the app.