Common issues
Common setup and runtime issues, and how to fix them.
Everything denies with deny.principal_mismatch
The single most common first-run stall. You get:
security.yaml: deny.principal_mismatch
hint: The attested principal matches no permit rule's agent, so no rule can ever match it; run
raxit without --agent to auto-derive the agent id, or set agent: <presented-principal> in
security.yaml.The identity your agent presents (--agent on raxit run, or RAXIT_AGENT_ID) doesn't match
agent: in security.yaml — so no rule can ever apply, not even a block rule, because
nothing in the policy references that principal at all. This is different from a normal
deny.default_or_forbid: the rule matching machinery never even got to a specific resource.
Fix: either drop --agent entirely and let raxit auto-derive the id, or set agent: in
security.yaml to exactly the id your agent presents. See
Agent identity & attestation for why identity is attested rather than
asserted in the first place.
raxit serve isn't reachable from status/plan/apply
raxit serve's own --addr flag defaults to :8080. Every client command
(status, plan, apply, agent) defaults its own --addr to localhost:8181. Start serve
with its bare default and the client commands that assume 8181 won't find it:
$ raxit status
Daemon:
[--] not reachable (localhost:8181) -- daemon may not be runningFix: start serve with --addr localhost:8181 explicitly (matching the client default), or
pass --addr :8080 to every client command. raxit dev's --listen flag already defaults to
localhost:8181, so this mismatch is specific to serve.
raxit serve refuses to start: missing approvals token
$ raxit serve --source .raxit/security.yaml
raxit serve: --approvals-token or RAXIT_APPROVALS_TOKEN must be set (approvals API is enabled
and the listener is not loopback-only)Fix: set RAXIT_APPROVALS_TOKEN=<token> before starting serve, or pass
--approvals-token. This only triggers when the listener isn't loopback-only — a purely local
raxit dev doesn't need it.
Port 8181 already taken by another project's daemon
If a daemon governing a different agent id is already bound to the port you're targeting,
raxit apply detects the mismatch and refuses to push to it rather than silently reconfiguring
someone else's daemon:
$ raxit apply
! daemon at localhost:8181 governs agent "default-agent", not "payments-bot" -- not pushing to it.
✓ Policy compiled + tested (.raxit/security.yaml)
✓ Enforce mode: on
policy hash: b9f3ff3d83cc
state recorded; the new policy is enforced by the next `raxit run`/`raxit serve` for this project.Exit code is still 0 — this is a refusal-with-recording, not a hard failure. Your policy is
compiled, tested, and saved locally; it takes effect the next time this project's own
run/serve starts (typically on a different port).
Fix: run a separate daemon on its own port for each project (--addr), or stop the other
project's daemon first if you actually meant to replace it.
Engine provisioning (RAXIT_ENGINE, offline/unsupported platforms)
The Python/TS SDK launcher resolves an engine binary through a tiered path: a pinned, checksum-
verified download by default, then PATH search. RAXIT_ENGINE is a deliberately unhashed
escape hatch — pointing it at a local binary bypasses the pinned-checksum resolution entirely.
If no usable engine is found through any tier (offline with no cached binary, or an unsupported
platform with no prebuilt artifact), the launcher fails closed rather than running ungoverned.
Fix: set RAXIT_ENGINE=/path/to/raxit to point at a binary you've built or downloaded
yourself when the pinned auto-fetch can't reach the network or doesn't support your platform.
raxit explain says "no record found" right after a run
$ raxit explain d867c63661454e8497369a08ebaec35d
explain: no record found for id "d867c63661454e8497369a08ebaec35d" in .raxit/var/dev-audit.jsonlexplain's default --audit path is .raxit/var/dev-audit.jsonl, but a daemon started with
raxit serve writes to .raxit/var/daemon-audit.jsonl by default instead. Looking up a call
made through a serve-started daemon against the dev default finds nothing.
Fix: pass --audit .raxit/var/daemon-audit.jsonl explicitly when looking up decisions made
through raxit serve (as opposed to raxit dev).
raxit approvals "unauthorized"
raxit approvals resolves its operator token in this order: --approvals-token/--token flag,
then RAXIT_APPROVALS_TOKEN env, then a local 0600-permission token file at
.raxit/var/approvals.token. On a local box the file is usually enough and nothing needs to be
passed explicitly — an "unauthorized" response usually means either the token file is missing/
unreadable, or you're pointed at a daemon on a different project/port that has a different token.
Fix: confirm you're targeting the right --addr, and check
ls -la .raxit/var/approvals.token exists and is readable; set RAXIT_APPROVALS_TOKEN
explicitly if you're crossing project directories.
raxit audit verify fails right after switching --agent
$ raxit audit verify --audit .raxit/var/daemon-audit.jsonl --agent totally-different-agent
audit verify: FAIL: this audit log's genesis was seeded for a different agent than
"totally-different-agent" (not tampering); pass --agent <the id the chain was created with>,
or start a new chainThis is not a tamper alarm — the chain's genesis hash is seeded from the agent id at
creation time, and verifying with a different --agent is a distinct, deliberately-separate
failure mode from an actual record_hash mismatch (tampered).
Fix: re-run with --agent matching whatever agent: the chain was actually created under
(it defaults to security.yaml's own agent: field if you omit the flag). See
Audit & the DPR chain for the genuine-tamper case, for contrast.
raxit uninstall refuses while a daemon is running
$ raxit uninstall
raxit uninstall: a daemon for this project is running at localhost:8181; stop it first
(Ctrl-C the running `raxit dev`/`raxit run` process, or kill its PID) before uninstallingThis check runs before any enumeration or deletion — deliberately fail-closed, so uninstall
never deletes a live daemon's workspace out from under it. Note this is separate from the
confirmation prompt you'll see once the daemon check passes:
$ raxit uninstall
This will permanently delete .raxit and everything in it, including:
.raxit/var/dev-audit.jsonl (audit trail, 1 records, 561B -- this is evidence)
.raxit/security.yaml (security policy, 693B)
.raxit/warrants.json (warrants, 235B)
.raxit/config.json (project config, 333B)
Type "yes" to continue: aborted; nothing removed
raxit uninstall: aborted (confirmation not given)Fix: stop the daemon first (Ctrl-C the raxit dev/raxit run process, or kill its PID),
then re-run raxit uninstall and type yes (or pass --yes for non-interactive removal). Note
the audit trail is explicitly called out as "evidence" in the confirmation — a deliberate
friction point before deleting compliance-relevant records.

