Mosh Diagnostics
Built-in test suite that pinpoints why a Mosh connection is failing.
Why It Exists
When Mosh refuses to connect — or worse, connects and then silently goes dead — the failure is usually one of a handful of root causes: UDP is blocked, mosh-server is not installed, the locale on the remote is wrong, or the remote is behind a firewall that drops idle UDP flows. Diagnosing this by hand means poking at iptables, checking which mosh-server, eyeballing locale, and trying again.
Mosh Diagnostics automates that. It is a built-in test runner that connects to a host the way vmux would, drives it through known-good and known-bad scenarios, and produces a structured report you can read or share.
Opening the Diagnostics Panel
The Mosh Diagnostics panel lives inside Settings:
- Open settings (Cmd+,) and switch to the Diagnostics section, or run Open Mosh Diagnostics from the Command Palette.
- The panel shows a runtime status line at the top — green if the Mosh runtime is available on this device, red if not (with the reason, e.g. "library not bundled in this build").
- Fill in the host you want to test, or tap Load From Active Profile to copy values from the connection profile of your currently focused window.
Diagnostics never write to your real connection. Each scenario opens its own short-lived test session.
Configuring a Run
| Field | Default | What it does |
|---|---|---|
| Enable on-device diagnostics | Off | Master toggle. Scenarios cannot run while this is off. |
| Host | empty | Hostname or IP. |
| SSH Port | 22 | Port for the bootstrap SSH session. |
| Username | empty | Remote user. |
| Control Script Path | /usr/local/bin/vmux-mosh-testctl | Path to the optional remote test-control script. Used by the Recovery and Diagnostics scenarios. |
| UDP Port/Range | 60000:61000 | UDP port range Mosh is allowed to use. |
| Connect Timeout Seconds | 20 | Per-step connection timeout. |
| Scenario Timeout Seconds | 45 | Total time-budget for one scenario. |
| Probe Command | printf '__VMUX_MOSH_DIAG__\n' | Shell command vmux runs on the remote to verify the session is interactive. |
Tap Save to persist your settings. They live in the same store as the rest of your vmux preferences.
What Each Scenario Does
There are six scenarios. You can run any one of them, or run Full Suite to execute all of them in order. Buttons are disabled while a run is in flight.
Baseline
The smoke test. Verifies that:
- The Mosh runtime is available on this device.
- The remote control script (if configured) responds to a preflight call.
- A Mosh session can connect, run the probe command, and respond to a window resize.
If Baseline fails, none of the other scenarios will pass either. Fix Baseline first.
Encoding
UTF-8 round-trip checks. Sends a known set of multi-byte sequences (é, a smiling-face emoji, an "e + combining acute" sequence) over both Mosh and SSH and verifies they survive intact. Catches cases where the remote LANG is wrong or mosh-server is built without UTF-8 support. Failure means the byte vectors did not match what arrived back.
Recovery
Resilience under network damage. Runs against a remote that has the test-control script installed; without it, this scenario cannot run.
- Connect baseline.
- Inject a 250 ms artificial delay (Linux
tc qdisc netem). - Verify Mosh still connects and responds under the delay.
- Clear the delay.
- Block UDP entirely on the configured range.
- Verify Mosh now fails to connect — and that the error message mentions UDP.
- Unblock UDP.
- Verify Mosh recovers.
This proves the connection roams correctly when your Wi-Fi flickers or you carry the headset between rooms.
Lifecycle
Background and foreground survival. Connects via Mosh, sends a probe, then waits for the app to be backgrounded and re-foregrounded. After return, it sends a second probe and verifies the same session is still alive. This catches regressions where vmux drops a Mosh session when you take the headset off briefly.
Diagnostics
The "is mosh-server actually working?" scenario.
- Stop
mosh-serveron the remote (via the control script). - Verify Mosh fails with an error that mentions
mosh-server. - Restart
mosh-server. - Verify Mosh connects again.
A failure here usually means mosh-server is not installed, is in an unusual location, or crashes on startup.
Regression
A plain SSH smoke test. Confirms SSH itself works against the same host so you can rule out "the network is just down." If Regression fails, your problem is upstream of Mosh — start by reading SSH Connections.
Full Suite
Runs Baseline, Encoding, Recovery, Lifecycle, Diagnostics, and Regression in order. The suite stops at the first scenario that fails internally only when the failure prevents later scenarios from making sense (for example, Diagnostics depends on the control script also used by Recovery).
Reading the Report
Each scenario produces a MoshDiagnosticsReport with a list of steps. The status line at the bottom of the panel shows the overall summary:
All diagnostics steps passed.or
One or more diagnostics steps failed.A more detailed report is written to disk. Tap Copy Report Path to put the path on your clipboard so you can hand it off via AirDrop, email, or by reading it on your Mac. The report is JSON and contains:
- The scenario name, start, and end timestamps.
- The app build and OS version.
- A snapshot of the connection profile (host, port, username, transport — no passwords or keys).
- Each step with a status (
passed/failed) and a free-formdetailstring. - A timeline of session-state transitions.
- A timeline of internal log events.
- The last 8 KB of terminal output produced during the run.
- Faults captured from the remote control script.
You can attach this file to a support ticket and the entire failure is reproducible from it.
Reading Common Failures
| Failure detail | Likely cause | Fix |
|---|---|---|
Runtime mode: ... unavailableReason: ... | The Mosh runtime is not available in this build. | Use a build that includes Mosh, or fall back to SSH. |
Unexpected final state: failed(...) mentioning mosh-server | mosh-server not installed or wrong path. | Install mosh-server on the remote. See Mosh requirements. |
Failure mentioning udp or bind | UDP blocked between you and the remote. | Open the configured UDP range on every firewall in the path. |
Encoding step says failed for: smile-emoji etc. | Remote locale is not UTF-8. | Set LANG=en_US.UTF-8 (or another UTF-8 locale) in the remote shell startup. |
Timed out waiting for expected probe output | Remote shell is not echoing the probe. | The user's shell may print a non-standard motd or trap stdout. Try a simpler probe command. |
preflight skipped (remote control script unavailable) | The control script is optional. | Install the script if you want Recovery / Diagnostics. Baseline alone works without it. |
Auto-Run for CI / Field Testing
Mosh Diagnostics can be triggered from the command line at app launch. This is mainly used by vmux engineers and advanced testers, but if you are bisecting a regression yourself it is the fastest way to capture a clean run.
Pass any of these flags or environment variables when launching vmux:
--mosh-diagnostics-auto # required to enable auto-run
--mosh-diagnostics-scenario=full # which scenario to run
--mosh-diagnostics-host=server.example.com
--mosh-diagnostics-user=alice
--mosh-diagnostics-exit-on-done # quit the app when the run completesEquivalent environment variables (VMUX_MOSH_DIAGNOSTICS_AUTO, VMUX_MOSH_DIAGNOSTICS_SCENARIO, etc.) are also accepted. When auto-run finishes, vmux emits stdout markers like:
__VMUX_MOSH_AUTORUN_BEGIN__|scenario=full|exit=1
__VMUX_MOSH_AUTORUN_END__|verdict=passed|report=/path/to/report.json|summary=All diagnostics steps passed.This is how vmux's own CI shells out to a real device for end-to-end network testing.
Related
- Mosh Connections — what Mosh is and how to set it up
- SSH Connections — fall back here when Mosh diagnostics shows the network is at fault
- Settings — where the diagnostics panel lives