Skip to main content
Each entry gives the symptom, the cause and the recovery. For single-node problems, see Ground Agent troubleshooting. Ground-station routes return errors in this shape:

PUT /role returns 409 E_MESH_NOT_CAPABLE

Symptom: a change to relay or receiver returns 409 with E_MESH_NOT_CAPABLE. Cause: the node does not carry two WFB-class radios (RTL8812EU or RTL8812AU). The agent checks the attached radios live on each request. Recovery:
Plug in a second RTL8812EU or RTL8812AU adapter. If it does not appear, check dmesg for driver bind messages. Once two WFB-class radios are present, mesh_capable reads true and the role change succeeds; no reinstall or reboot is needed.

PUT /role returns 409 E_NOT_PAIRED

Symptom: a change to relay returns 409 with E_NOT_PAIRED. Cause: the node has no mesh id or shared key on disk. The agent refuses the relay role until mesh pairing has stored them, so the mesh service does not restart in a loop. Recovery:
  1. Bring the receiver up first if it is not already.
  2. On the receiver, open the accept window (Mission Control Mesh & RX, or POST /api/v1/ground-station/pair/accept).
  3. On this node, still in direct, join with the code (POST /api/v1/ground-station/pair/join).
  4. Approve it on the receiver, then retry the role change.
See Build a mesh.

Accept window shows no pending relay

Symptom: the receiver’s accept window is open, the relay sent its join, but GET /api/v1/ground-station/pair/pending (or Mission Control Mesh & RX) shows nothing pending. Cause one: the join did not reach the receiver because the nodes cannot reach each other.
Cause two: the relay joined before the window opened. Open the window first, then join. Cause three: the receiver’s pairing listener could not bind UDP port 5801.
A pairing_bind_failed entry means the port is taken. Find the owner with sudo lsof -i :5801.

Join fails with E_INVITE_REJECTED

Symptom: POST /pair/join returns 503 with E_INVITE_REJECTED. Cause: the receiver’s replies did not open under the code the relay sent. Usually the code was mistyped, or it belonged to an earlier window. Recovery: read the code the receiver shows for the current window and join again.

Relay stored the invite but stays in direct mode

Symptom: the join succeeded, but the relay’s role still reads direct. Cause: pairing stores the mesh identity; it does not change the role. Recovery: change the role to relay (Mission Control Mesh & RX, the LCD Mesh page, or PUT /api/v1/ground-station/role). See Add a relay.

Receiver picks the wrong cloud gateway

Symptom: the receiver sends cloud traffic through a slow gateway when a faster one is available. Cause: batman-adv ranks gateways by mesh link quality (TQ), not uplink speed. Recovery: pin the gateway you want. See Cloud gateway election.

Receiver shows a partition

Symptom: Mission Control shows the partition indicator; some neighbours disappear while the local mesh interface stays up. Cause: the mesh has split: a node lost power, interference dropped a link, or something is blocking the path between nodes. Recovery: batman-adv re-merges on its own once a path returns. If the split persists, check power and antenna placement on the missing nodes.

Stale mesh state after a role change

Symptom: Mission Control shows a relay or stream that is no longer on the mesh. Cause: an interrupted role change left an old snapshot in /run/ados/. A normal role change clears it. Recovery: change the role to direct, then back:
Use the node’s previous role in the second call.

Accept returns 503 E_PAIR_DAEMON_UNAVAILABLE

Symptom: POST /api/v1/ground-station/pair/accept returns 503 with E_PAIR_DAEMON_UNAVAILABLE. Cause: the pairing service is not running, or it refused to open the window (the message says why). Recovery:
Then open the window again.

Next steps

Build a mesh

The full pairing and role flow.

Local mesh (batman-adv)

The carrier and diagnostics.
Last modified on October 11, 2026