MeshMonitor 4.16.0
The first full release since 4.15.2, after six release candidates.
The headline work is reliability on large meshes. A reporter with a ~190-node NodeDB packet-captured MeshMonitor dropping its TCP link partway through every config sync, and the fix took four passes: a connect timeout that could outlive its own attempt and kill a healthy socket, a favorite write-back that injected an admin packet into the middle of the NodeDB stream, a stalled sync that hung with no detection at all, and finally a fast-retry ramp so recovery takes ~16s instead of ~73s. Alongside that, map route segments now honour the Show RF / UDP / MQTT toggles, the Sources list shows unread DM counts per source, and operators can publish privacy, terms and contact documents from inside MeshMonitor. Device credentials are no longer written to debug logs.
⚠️ Upgrade notes
Route segments will disappear from your maps. Show MQTT and Show UDP default to off, and as of this release those toggles filter traceroute route segments as well as node markers. Nothing is deleted — turn Show MQTT on in the Map Features panel to get them back. See Transport filtering and route segments.
MeshCore TCP sources now default to port 5000. That is where MeshCore's WiFi and Ethernet companion builds listen. If you run a native-TCP build, it still uses 4403 — set the port explicitly when adding the source.
Two new migrations run on first boot (160, 161) plus one from the privacy feature (162). All are additive and idempotent. Traceroutes recorded before this release carry no transport information and are treated as RF, so they stay visible under the default toggles.
Features
- Route segments respect the Show RF / UDP / MQTT map toggles (#5097)
- Per-source unread DM badge on the Sources list, with a per-user off switch (#5124)
- Operator privacy disclosures: hosted or linked privacy policy, terms and contact documents (#5156)
- Philadelphia MeshCore 500 radio preset (#5137)
- MeshBeacon warns on regulator-non-compliant preset/region combinations in received offers (#5103)
- MeshCore observer device stats and noise-floor telemetry from the
/statustopic (#5040)
Bug fixes
Large-mesh TCP reliability (#5122)
- Scope the connect timeout to its own attempt, and name every socket teardown
- Defer the favorite write-back out of the initial config sync
- Detect a stalled config sync instead of hanging indefinitely
- Retry sooner after a mid-sync disconnect, ramping 3s → 10s → 30s
MeshCore
- Default the TCP source port to 5000, not 4403 (#5160)
- Decode RepeaterStats and Core stats fields the pinned library dropped (#5125)
- Guard an unhandled-rejection crash from bare library rejects (#5102)
- Refresh
lastHeardon telemetry round-trip, not just adverts (#5131) - Route MQTT ingest sources through every MeshCore read path, and give them their own page (#5094, #5096)
- Theme the MeshCore MQTT ingest inputs and channel/room row buttons (#5135, #5071)
Maps and UI
- Give the Leaflet credit room beside the packet monitor (#5099)
- Stop chart panels overflowing the viewport in portrait (#5093)
- Keep the GPIO Pin Usage sidebar inside the viewport (#5100)
- Scope the non-scrollable-page rule to the channels tab
Configuration and data
- Move Traffic Management to the v2.8 non-zero-enables schema (#5123)
- Scope traceroute purges, and guard the sibling that never did (#5088)
- Stamp the security load gate from the per-section load too (#5077)
- Request the survey under
/apiso it reaches the API router (#5078)
Security
- Device credentials are no longer written to debug logs in the clear (#5141). WiFi PSK, MQTT password, private and admin keys are redacted;
publicKeystill prints in full by design.
Documentation
The docs were audited against every change since 4.15.2 before this release. The MeshCore setup page named the wrong TCP port, the privacy feature had shipped with no documentation, the unread badge was undocumented, and the transport filter was described as affecting markers only. All corrected (#5169). The Features navigation was also reorganised — 8 sidebar groups became 12, none over six rows, and the ten root-level pages now render with a sidebar instead of none. No URLs moved.
Also added: the community EmComm Control script by @maxhayim to the User Scripts gallery (#5166, #5165).
CI
- Drop the runner's Chrome apt source before the security scans (#5160). A broken upstream mirror was failing ClamAV and Trivy before either tool ran, so a red check meant "apt could not reach Google" while looking exactly like "we found something".
- Run the release coverage gate on Node 22 rather than Node 24 (#5158)
- Re-fetch previously published Helm chart archives on redeploy (#5119)
Dependencies
20 Dependabot updates across production and development groups, including @tanstack/react-query, maplibre-gl, mysql2, openid-client, express-rate-limit, lucide-react, puppeteer, eslint and the vitest group.
Full changelog: v4.15.2...v4.16.0