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, 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 (Chats), 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.

14.5 Automatic housekeeping (no action required)

The engine maintains itself:

Task Cadence
Peer presence staleness sweep (online → away → 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.