Skip to content

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 gridx on 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.sh script (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_health status (healthy/degraded with reasons) surfaced in network status.
  • Pi/desktop: journalctl -u gridx -f (or the engine's console) and rnstatus for 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

  1. Confirm both devices have a common transport enabled (same WiFi, matching LoRa parameters, or both reaching a gateway).
  2. Use Refresh routes (Settings → Network) or Add personnel (announce) on both sides.
  3. On LoRa, verify all radio parameters match exactly (Chapter 5) — a bandwidth or spreading-factor mismatch is silent.
  4. 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.