Skip to content

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         # edge

doctor --fix applies the thin remediations it can (e.g. restarting a down service); --yes skips the prompts.

Install (all components)

SymptomCauseFix
macOS Gatekeeper blocks a downloaded binaryThe 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 missingminisign is the trust root and is never auto-fetchedInstall 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/binInstall 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.

SymptomCauseFix
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 updateburrowee 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 driftThe updater binary itself was updated but its own service unit hasn't restartedRestart 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 runningThe console mirrors the last state the component reported; a very recent restart hasn't reported yetGive 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 installsRe-run without --dry (or with --auto to skip the confirmation prompt)
A console push-update is refused / never lands on a gateway or edgePush 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 runningburrowee 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

SymptomCauseFix
bootstrap hangs at "waiting for approval…" then times outApproval must come from the gateway's local console on the gateway host — not console.burrowee.comHave 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 blobAsk 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 fileRun 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 editedRe-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 scratchStale or revoked pairingrm -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

SymptomCauseFix
Gateway doesn't appear online in console.burrowee.comThe 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 allburrowee gateway service status; restart without --console off. burrowee gateway console prints the URL + a start hint
service install fails on Linux: no systemdNon-systemd init (OpenRC, runit, …)Run burrowee-gateway foreground under your own supervisor (ExecStart=burrowee-gateway --no-open equivalent)
bootstrap error: "wrong PIN" / decrypt failureBlob and PIN must match exactly (case-sensitive blob, digit PIN)Regenerate from console.burrowee.com → Gateways → Generate setup
Need to re-bootstrap from scratchWiping config, relays, and identityStop 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

SymptomCauseFix
"awaiting approval" never flips to activeThe operator approved a different edge, or is signed into the wrong accountConfirm 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 unreachableThe edge only talks to the compiled-in Burrowee console — no overrideCheck the host's outbound HTTPS/WSS to the console; honor HTTPS_PROXY if behind a proxy
doctor shows custom-domain cert ✗ for a whileDNS propagation + Let's Encrypt issuance take timeConfirm the _acme-challenge CNAME resolves to <slug>.acme.burrowee.net, then re-run doctor after a few minutes
service install fails: systemd not availableNon-systemd initRun burrowee edge run foreground or under a custom supervisor
status: "enrolled; no config received yet"The edge hasn't connected while approvedRun burrowee edge run while approved + connected, then re-check
Unhealthy nginx LAN frontSnippet missing, not applied, or nginx downburrowee 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 scratchWiping the edge identityrm -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 secondsburrowee-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 eventsudo 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.