Chapter 14 — Maintenance & Troubleshooting¶
14.1 Data locations and backup¶
All device data lives in the profile directory: ~/.gridx on desktop/Pi (GRIDX_HOME overrides it), or the app's private container on mobile.
| File / directory | Contents |
|---|---|
device.identity |
The device's private identity keyset. This is the device's identity — guard it accordingly. |
messages.db |
SQLite store: messages, peers, groups, reactions, GPS positions, quarantine, trust grants, orgs. |
config.json |
Profile: display name, team, role, avatar color, radio region, setup state. |
reticulum/config |
The engine's network configuration: interfaces, radio parameters, IFAC, transport flag. |
media/ |
Attachment storage. |
lxmf_storage/ |
Message-router storage. |
ws_token |
The per-boot local API token (regenerated every start). |
vendor.cert |
Vendor device certificate, if installed. |
Backup guidance: back up the whole profile directory with the engine stopped. Restoring it to a new machine restores the identity, history, and configuration wholesale. Remember that the backup can impersonate the device — store it as securely as the device itself (Chapter 10).
14.2 Restarting vs. resetting¶
- Restart — Settings → Network → Restart backend (or
sudo systemctl restart gridxon a Pi). Drops the mesh link for a few seconds; state and identity are untouched. Required after interface/radio/IFAC changes. On mobile, fully relaunch the app instead — the embedded engine cannot restart in place. - Factory reset — the
stolo_reset.shscript (desktop/dev) stops every Stolo process and deletes the entire profile directory: identity, all message history, configuration, media, and the vendor certificate. There is no confirmation and no undo, and the device returns to the mesh as a new identity (peers will see the old identity linger until it ages out of their rosters). Use it only when a clean slate is genuinely intended.
14.3 Reading engine health¶
- In-app: the mesh banner (Messages), per-interface status (Settings → Interfaces), and Settings → Network's status card. The engine also pushes a
mesh_healthstatus (healthy/degraded with reasons) surfaced in network status. - Pi/desktop:
journalctl -u gridx -f(or the engine's console) andrnstatusfor interface-level detail.
Log lines worth knowing:
| Log signature | Meaning / action |
|---|---|
INTERFACE: <name> type=... bitrate=... at startup |
Interface came up. Missing entries = config problem. |
booting DEGRADED (mobile) |
The WiFi interface wasn't ready within 10 s of launch; mesh is offline this session — relaunch after WiFi settles. |
announce-wedge protection is INACTIVE |
A software-update mismatch disabled a TCP resilience patch; report to support before fielding. |
mesh degraded: [...] |
The engine detected a wedged/stale interface and is self-healing; persistent recurrence merits a restart. |
throttle: dropping ... |
Sustained announce/path-request overload — usually transient. |
[ws-watchdog] listener dead ... rebinding |
Normal recovery after an iOS suspension; repeated rebind failed is a problem. |
14.4 Common issues¶
A peer shows "Finding a route…" indefinitely¶
- Confirm both devices have a common transport enabled (same WiFi, matching LoRa parameters, or both reaching a gateway).
- Use Refresh routes (Settings → Network) or Add personnel (announce) on both sides.
- On LoRa, verify all radio parameters match exactly (Chapter 5) — a bandwidth or spreading-factor mismatch is silent.
- Check the Connections screen: is the expected connection Active and showing peers/bitrate?
Messages stuck at "Sent" / "Held on relay"¶
This is usually correct behavior: the recipient is off the air and the message is waiting. Priority/Critical messages retry automatically; Standard messages auto-recover for 24 h when the peer reappears. If the sender believes the recipient is online, check the recipient's phone hasn't suspended the app (Background mesh off → a locked phone receives nothing until unlocked).
Radio not detected¶
- USB (desktop/Pi): confirm the RNode appears as a serial device; on Linux ensure the user is in
dialout(the Pi installer does this) and restart the engine. Auto-configuration runs at engine start. - Bluetooth: put the RNode in pairing mode (hold button ~3 s), ensure it's OS-paired, and remember BLE and USB are mutually exclusive for one radio.
The app shows "Cannot connect to Stolo backend"¶
The UI lost its loopback link to the engine. Tap RETRY; on desktop confirm the engine process is running. On mobile this can follow a long suspension — reopening the app reattaches within a few seconds.
WiFi network changed and local peers vanished¶
After roaming networks or toggling WiFi, the engine rebuilds its local interface automatically when it detects the change; if peers don't return within a minute, use Settings → Network → Restart backend.
"Setup not complete" errors from the API¶
The engine hasn't finished first-run setup — complete setup in the app (or via the complete_setup API action) before other calls.
Quarantine keeps filling from an unwanted sender¶
Use Deny & Block with a duration (Chapter 7) — blocking purges that sender's pending quarantine entries and drops future traffic at the network layer. For unattended devices, consider Strict mode.
License troubles¶
See Chapter 9 — activation error messages are specific and actionable (seat occupied, code consumed, subscription lapsed, network unreachable). Remember activation/renewal are the only operations that need internet.
14.5 Automatic housekeeping (no action required)¶
The engine maintains itself:
| Task | Cadence |
|---|---|
| Peer presence staleness sweep (active → idle → offline) | every 60 s |
| Message retry queues (priority/critical) | every 15 s |
| Delivery timeout classification | every 30 s |
| Presence re-announce | every 5 min |
| GPS broadcast (movement/freshness-gated) | every 60 s |
| Quarantine expiry purge (7-day TTL) | hourly |
| Interrupted retries re-queued | at every start |
14.6 Updates¶
- Mobile/desktop apps update through their normal channels; engine data migrates automatically in place.
- Pi relay nodes:
cd ~/gridx && git pull --recurse-submodules && sudo systemctl restart gridx. - Versions in play (app, RNS, LXMF, OS, Python) are shown at Settings → Network → System and in the Settings footer — include them in any support request.
14.7 Getting help¶
Include with any report: platform and app version, the Settings → System versions, what the mesh banner and Connections screen showed, and (Pi/desktop) the relevant journalctl -u gridx excerpt. No message content is ever needed for network diagnostics.