Troubleshooting

You ran the installer. The progress bar filled, the terminal went quiet, and now you’re staring at one red light that was definitely not in the screenshots. No stack trace, no context — just vibes and a failing probe. Welcome: this is the page for exactly that moment. The symptoms below are the ones we see the most, and the fixes are the durable ones — no workarounds, no “try restarting it” cargo-culting.
If your specific failure isn’t listed, run sanctum doctor first and actually read its output. Doctor’s green but something’s still cursed? Bring that output to the Sanctum channels.
Doctor and self-test
Section titled “Doctor and self-test”sanctum doctor shows the Firewalla bridge FAILED. Now what?
sanctum doctor walks your com.sanctum.* LaunchAgents and reports each one’s status. The Firewalla bridge runs under com.sanctum.firewalla-bridge-watchdog; if the doctor flags it, the watchdog isn’t keeping a healthy bridge alive on :1984.
The bridge doesn’t read a Firewalla IP from any config file — it discovers the Firewalla and caches the result. So the question is rarely “is the IP wrong,” it’s “is the bridge process up”:
# Is anything listening on the bridge port?lsof -nP -iTCP:1984 -sTCP:LISTEN
# What IP did the bridge discover for your Firewalla?cat ~/.openclaw/firewalla/keys/topology.jsonIf nothing’s on :1984, kick the watchdog and let it respawn the bridge:
launchctl kickstart -k gui/$(id -u)/com.sanctum.firewalla-bridge-watchdogIf topology.json shows an IP but the bridge still can’t reach it, that’s a network problem, not a Sanctum problem. Check you’re on the same LAN as your Firewalla — a different WiFi SSID can drop you onto a guest subnet that can’t reach the Firewalla’s management VLAN, and discovery will keep serving a stale cache.
Every authenticated request to the Firewalla bridge gets a 401
The bridge can’t find its bearer token. It reads the filesystem secret at ~/.sanctum/secrets/firewalla-bridge-token first, and only falls back to the Keychain item (service firewalla-bridge-token, account sanctum) for legacy user-session setups. If neither is present, every authenticated request to localhost:1984 gets refused. Fix the filesystem store first — that’s the one the bridge actually reads.
# Is the filesystem secret there at all?cat ~/.sanctum/secrets/firewalla-bridge-token
# If it's empty or missing, mint a strong one and write it to the primary store.TOKEN=$(openssl rand -hex 24)printf '%s' "$TOKEN" > ~/.sanctum/secrets/firewalla-bridge-tokenchmod 600 ~/.sanctum/secrets/firewalla-bridge-token
# Legacy fallback only: if you're on an older Keychain-based setup, store it there too.security add-generic-password -s firewalla-bridge-token -a sanctum -w "$TOKEN"
# Restart the bridge so it re-reads the token.launchctl kickstart -k gui/$(id -u)/com.sanctum.firewalla-bridge-watchdogThe authed endpoints should stop 401-ing once the bridge comes back up.
sanctum devices says no devices.yaml found
The screen-time device inventory lives at ~/.sanctum/screen-time/devices.yaml (symlinked into the screen-time module). If sanctum devices can’t find it — or finds it empty — there’s nothing to list.
# Confirm where sanctum is looking.sanctum devices # prints the two paths it checks when the file is missingsanctum devices is read-only by design, so there’s no add subcommand — you seed the file by editing it. The schema is keyed by family: (each member has personal_devices:) and shared_devices:, not a flat list:
family: kid1: name: Sam personal_devices: - { name: "Sam's iPhone", mac: "FA:CE:DE:CA:CA:01" }shared_devices: living_room_appletv: { name: "Living Room Apple TV", mac: "FA:CE:DE:CA:CA:02" }For now, this YAML is the source of truth — you edit it by hand.
sops can’t decrypt — the secrets layer is offline
Your sops/age key was never generated. Sanctum needs it to encrypt and decrypt the secrets it ships with — without ~/.config/sops/age/keys.txt, every sops decrypt fails and the secrets layer goes dark.
# Is the key there?ls -l ~/.config/sops/age/keys.txt
# If not, generate one.mkdir -p ~/.config/sops/ageage-keygen -o ~/.config/sops/age/keys.txtOnboarding should have done this for you; if it didn’t, the command above is the fix.
Install and first-run
Section titled “Install and first-run”My screen-time PWA shows someone else’s haus name
The PWA’s name is hardcoded in its source — manifest.json and index.html ship with a haus name baked in. So you rename it by hand against the real PWA path:
PWA=~/Projects/sanctum-screen-time/pwased -i '' 's/Manoir [A-Za-z]*/Your Haus Name/g' "$PWA/index.html"sed -i '' 's/Manoir [A-Za-z]*/Your Haus Name/g' "$PWA/manifest.json"Refresh the PWA in your browser. If it still shows the old name, hard-reload to bust the service worker cache (Cmd-Shift-R on macOS Safari/Chrome, or uninstall and reinstall the PWA from the share sheet — a stale sw.js is the usual culprit).
sanctum self-test shows every haus-tier probe red at once
sanctum status (disk, backup, telemetry) doesn’t depend on the agent layer, so it stays green — but if every haus-tier self-test probe (cathedrals, proxyd, Force Flow, chitti) fails together, the usual cause is upstream of all of them: the Lima VM didn’t come up on boot. The agent layer lives in the VM; when it’s down, everything downstream looks dead.
LIMA_HOME=$HOME/.lima limactl start sanctum-vm --tty=falseIf that succeeds, re-run sanctum self-test — the haus probes should come back within a minute. If limactl start itself fails, read the autostart log directly (there’s no sanctum logs alias for it):
tail -n 50 ~/.openclaw/logs/vm-autostart.logThe two usual failure modes: (1) socket_vmnet isn’t running (brew services list | grep socket_vmnet should say started), and (2) macOS popped a sudo prompt the autostart script can’t answer (the sudoers entry should have prevented it — sudo -n true 2>&1 to check).
Operational signals
Section titled “Operational signals”Firewalla bridge log says 60s without successful op (via cache)
That’s a misleading discovery-checker log line, not a real failure. The bridge’s discovery loop runs every 60 seconds; if a probe lands between Firewalla-API calls, the loop logs the gap and falls back to its cache. The data it returns is still correct.
Look for [error] lines instead — those are the real signal. If the discovery message is all you see, the bridge is healthy.
How do I uninstall Sanctum?
Two flavors:
# Preserves your data (devices.yaml, schedules, encrypted secrets, logs).# If you reinstall later, you pick up where you left off.sanctum uninstall
# Removes everything Sanctum-managed, including your data.sanctum uninstall --purgeThe age-key backup you made earlier survives both — it lives on the USB drive / password manager you put it on, not on the Mac. As long as you have that file, you can decrypt your old secrets even after --purge.
Where should I store my age-key backup?
Anywhere that isn’t your Sanctum-managed Mac. Sanctum doesn’t probe for it, doesn’t depend on it being in any particular place, and doesn’t push it anywhere on your behalf.
Some shapes that work:
- A USB drive in a desk drawer
- An encrypted disk image (
hdiutil create -encryption -size 100m -volname sanctum-keys ...) - A password manager attachment (1Password, Bitwarden, etc — but the backup itself, not a screenshot)
- A second Mac, copied via AirDrop or scp, stored in a similarly safe spot
The one shape that doesn’t work: leaving it in ~/Desktop/ on the same Mac. The whole threat model here is “Sanctum’s Mac dies or gets stolen.” If your only copy is on that Mac, you have zero recovery path and your sops secrets become unrecoverable. Anywhere else, you’re golden.
When in doubt
Section titled “When in doubt”sanctum doctor is the first stop. sanctum self-test is the second. If both are green and something is still wrong, the issue is probably specific enough that it deserves a real bug report — file it in the Sanctum channels with:
- The
sanctum doctoroutput - The
sanctum self-testoutput - The contents of
~/.sanctum/instance.yaml(with any secrets redacted) - A description of what you expected to happen and what happened instead
The maintainers read these. The fix usually ships in the next pilot point-release.