Appearance
Troubleshooting
Common failures and their fixes, grouped by component. Each component also ships a built-in diagnostic — start there:
sh
burrowee doctor # cli
burrowee gateway doctor # gateway
burrowee edge doctor # edgedoctor --fix applies the thin remediations it can (e.g. restarting a down service); --yes skips the prompts.
Install (all components)
| Symptom | Cause | Fix |
|---|---|---|
| macOS Gatekeeper blocks a downloaded binary | The quarantine attribute on a manually downloaded file (the signed installer flow doesn't hit this) | xattr -d com.apple.quarantine ./burrowee-cli (repeat per binary) |
| Installer aborts: minisign missing | minisign is the trust root and is never auto-fetched | Install it from your package manager (brew install minisign / apt-get install minisign) and re-run |
burrowee <component> → "is not installed on this machine" (exit 127) | The dispatcher found no burrowee-<component> (or, for gateway/edge, its -cli sibling) on PATH or in /usr/local/bin, /opt/homebrew/bin, ~/.local/bin | Install the missing component from Install, or check the bin dir is on PATH — the installed here: … line lists which components are installed here so you can tell a missing install from a PATH problem |
Updates & versions (all components)
Every component's status/doctor/--version output prints a versions block showing the binary installed on disk next to the version actually running as a service.
| Symptom | Cause | Fix |
|---|---|---|
Versions block shows "⚠ drift" (installed vX · running vY) | An update replaced the binary on disk (or a push update landed) but the running service hasn't restarted onto it yet — normal right after update --no-restart, or briefly during a console-pushed update | burrowee cli restart / burrowee gateway restart / burrowee edge restart restarts the affected daemon onto the installed binary. See CLI updates, Gateway service, Edge operations |
An updater agent (burrowee-gateway-updater / burrowee-edge-updater) shows drift | The updater binary itself was updated but its own service unit hasn't restarted | Restart its unit directly: macOS launchctl kickstart -k gui/$(id -u)/com.burrowee.gateway.updater (edge: org.burrowee.edge-updater); Linux systemctl --user restart burrowee-gateway-updater.service (edge: burrowee-edge-updater.service) — there's no dispatcher shortcut for the updater itself |
| Console shows an older version than what's actually running | The console mirrors the last state the component reported; a very recent restart hasn't reported yet | Give it a moment, or check the authoritative local state with burrowee <component> status |
update --dry reports a version but nothing changes | --dry only checks for a newer release + prints the changelog — it never installs | Re-run without --dry (or with --auto to skip the confirmation prompt) |
| A console push-update is refused / never lands on a gateway or edge | Push needs both the opt-in (allow_push_update) and a connected standalone updater agent — a node can be online with push enabled yet still refuse if its updater agent isn't running | burrowee gateway updater doctor / burrowee edge updater doctor (--fix starts the agent); check the opt-in with push status. On an edge, push allow also (re)starts the agent |
CLI
| Symptom | Cause | Fix |
|---|---|---|
bootstrap hangs at "waiting for approval…" then times out | Approval must come from the gateway's local console on the gateway host — not console.burrowee.com | Have the gateway operator check the local console for the pending pairing request and approve it. If it never appeared, the blob may reference the wrong relay — ask for a fresh blob |
| "decrypt blob (wrong PIN?)" | The PIN doesn't match the blob | Ask the gateway operator to confirm the PIN or generate a fresh blob+PIN pair |
"no usable client config … run burrowee bootstrap" / "gateway public key required (--gw-pub)" | No gateway is paired yet (config.json has no gateways/edges), or you passed --gw-pub explicitly pointing at a missing/unreadable file | Run burrowee bootstrap <blob> <pin> first — the matrix stores gateway key material inline in config.json now, so --gw-pub/--psk are only needed to override it explicitly, not to supply it |
| "daemon: config incomplete" | config.json is absent or was manually edited | Re-run bootstrap to regenerate it |
relays list fails with "connect: no such file" | The transport daemon isn't running (relays list is a pure IPC call) | burrowee daemon or burrowee service install. Note relays use <id> still works — it persists to config.json first and only warns about the down daemon |
| Need to re-pair from scratch | Stale or revoked pairing | rm -rf ~/.burrowee/cli, then bootstrap again with a new blob+PIN from the gateway operator (they can revoke the old pairing in their local console) |
Gateway
| Symptom | Cause | Fix |
|---|---|---|
Gateway doesn't appear online in console.burrowee.com | The relay URL in the blob isn't reachable from the gateway machine (outbound WSS) | Check ~/.burrowee/gateway/gateway.db exists (bootstrap wrote it), check the service logs for dial errors, and confirm outbound HTTPS reachability of the relay host — e.g. curl -v https://relay.example.com |
Local console unreachable (http://127.0.0.1:16518) | The daemon started with --console off, or isn't running at all | burrowee gateway service status; restart without --console off. burrowee gateway console prints the URL + a start hint |
service install fails on Linux: no systemd | Non-systemd init (OpenRC, runit, …) | Run burrowee-gateway foreground under your own supervisor (ExecStart=burrowee-gateway --no-open equivalent) |
bootstrap error: "wrong PIN" / decrypt failure | Blob and PIN must match exactly (case-sensitive blob, digit PIN) | Regenerate from console.burrowee.com → Gateways → Generate setup |
| Need to re-bootstrap from scratch | Wiping config, relays, and identity | Stop the service first — macOS: launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.burrowee.gateway.plist; Linux: systemctl --user stop burrowee-gateway.service — then rm -rf ~/.burrowee/gateway and bootstrap again (the console issues a new enrollment) |
Service logs — macOS: log show --predicate 'process == "burrowee-gateway"' --last 1h (plus ~/.burrowee/gateway/logs/); Linux: journalctl --user -u burrowee-gateway.service -f.
Edge
| Symptom | Cause | Fix |
|---|---|---|
| "awaiting approval" never flips to active | The operator approved a different edge, or is signed into the wrong account | Confirm the fingerprint shown in the portal matches the one bootstrap printed, and that the approver is the owner-tier account that minted the blob |
| Console unreachable | The edge only talks to the compiled-in Burrowee console — no override | Check the host's outbound HTTPS/WSS to the console; honor HTTPS_PROXY if behind a proxy |
doctor shows custom-domain cert ✗ for a while | DNS propagation + Let's Encrypt issuance take time | Confirm the _acme-challenge CNAME resolves to <slug>.acme.burrowee.net, then re-run doctor after a few minutes |
service install fails: systemd not available | Non-systemd init | Run burrowee edge run foreground or under a custom supervisor |
status: "enrolled; no config received yet" | The edge hasn't connected while approved | Run burrowee edge run while approved + connected, then re-check |
| Unhealthy nginx LAN front | Snippet missing, not applied, or nginx down | burrowee edge doctor --fix (install → apply → start), or re-run sudo burrowee edge nginx reconcile --mode lan yourself (preview the legacy combined config with burrowee edge nginx apply --print) |
| Need to re-pair from scratch | Wiping the edge identity | rm -rf ~/.burrowee/edge, then bootstrap again — the console-side pending row must be re-minted |
| Edge flaps every ~12s on a Linux host set up over SSH: Cloudflare 525s, direct clients see connection reset, bridge links spam "down" every few seconds | burrowee-edge installs as a systemctl --user service, which Linux tears down ~12s after the last login session closes unless linger is enabled — the daemon's Started timestamp will exactly match each sshd Accepted publickey event | sudo loginctl enable-linger <user> on the edge host, then confirm with systemctl --user show burrowee-edge -p ActiveEnterTimestamp across two separate SSH logins — it should stay identical instead of bumping on each login. See Edge operations |
Rotating the LAN cert invalidates pins
There is no rotate flag — to force a new LAN certificate, stop the service, delete ~/.burrowee/edge/lan-cert/, and re-run sudo burrowee edge nginx reconcile --mode lan (see Rotating the LAN certificate). Every client/gateway that pinned the old fingerprint must re-paste a fresh blob afterwards (gateways heal automatically on the next endpoint report; CLI clients do not). It's a deliberate operator act, not part of routine renewal — the LAN cert is long-lived by design.