Troubleshooting
The errors grith actually produces, what each one means, and the fix.
grith fails closed. Most of what goes wrong shows up as a refusal to start a session rather than a session that silently runs unsupervised, so the errors below are mostly grith telling you it will not proceed.
A session will not start
daemon not ready (version_mismatch)
grith exec is a thin client. It will not supervise anything without a daemon of exactly its own
version, and it has no in-process fallback - if the daemon is not right, your command is never
started at all. After an upgrade the old daemon is usually still listening:
$ grith daemon restartThe same refusal appears with other codes, each with its own remedy: port_owned_by_foreign_process
(something else holds 3141), token_rejected and not_ready (restart), audit_quarantined and
audit_read_only (below). Every one of them says No supervised session was started and then
names the fix.
server.enabled is false in your configuration
Supervision needs the daemon for the session cap and the single audit writer, so with the server
disabled grith exec refuses rather than supervising with weaker guarantees. Set
server.enabled = true and retry.
The audit chain is quarantined
A session whose decisions cannot be verifiably recorded is not a supervised session, so the daemon admits none. Every existing record is preserved unmodified - nothing is rewritten at startup. Diagnose is read-only and is the one audit command that still works in this state:
$ grith audit diagnose
Chain status: writable
Full verification: chain is empty.
Segments: 1 (continuous history)
Duplicate sequences: none.
Sequence gaps: none.
Assessment: no integrity problems detected.That is a healthy chain. A quarantined one names the reason instead, and reports forks, duplicate sequences and gaps.
ptrace is not permitted
grith needs CAP_SYS_PTRACE or Yama ptrace_scope set to 0 or 1. Ubuntu and Debian ship 1, which
is fine; some hardened images use 2 or 3, which is not.
$ cat /proc/sys/kernel/yama/ptrace_scopeIf it reads 2 or higher, either lower it (sudo sysctl kernel.yama.ptrace_scope=1, persisted in
/etc/sysctl.d/) or run grith as a user holding CAP_SYS_PTRACE.
aarch64 supervision requires PTRACE_GET_SYSCALL_INFO (Linux kernel 5.3 or newer)
On arm64 grith reads the kernel's own syscall record; there is no fallback for older kernels, because the pre-5.3 paths are x86-shaped and would misclassify rather than fail. x86_64 needs 4.8 or newer.
The daemon
Port 3141 is in use by a process that is not a Grith daemon
grith will not evict a process it cannot identify as its own. Free the port, or move grith:
$ grith config set server.port 3142grith daemon status distinguishes the three cases honestly - a grith daemon (naming its
version), a foreign process, or nothing at all.
Config
Every command fails with supervisor.default_profile must be set
A hand-written sparse config.toml is the usual cause. Config layers merge as whole structures,
so a file that omits a key still contributes that key's built-in default and overwrites the
shipped value - and the built-in default for default_profile is empty, which fails validation.
$ grith --config config.toml config
Error: configuration invalid:
supervisor.default_profile must be set in TOML or via GRITH_SUPERVISOR_PROFILEStart from what grith init writes, or use grith config set, which always writes a complete
file. The same merge behaviour also silently raises supervisor.max_concurrent_sessions from 4 to
64 and changes the default model names, so it is worth avoiding for more than this one error.
Things that look broken and are not
The tool stopped and nothing is on screen
A permission prompt is waiting. In grith exec it is in the session window; if the session is
headless there is no prompt and the call was denied instead. Note that only the calling thread is
held - the rest of the tool keeps running, which is why a TUI carries on rendering while a
decision is outstanding.
Everything that needed review was denied, with no prompt
That is the headless fail-closed path. See Running grith in CI.
grith canary add prints a token, grith canary list shows nothing
Working as built. The CLI mints into its own in-memory registry and exits. Durable registration
means writing config/filters/canary.toml and restarting the daemon - see
Setting up canary tokens.
DNS stopped working inside a --workspace-only session
The workspace boundary exempts reads of system runtime roots, including the resolver's runtime
directories (/run/systemd/resolve/, /run/resolvconf/, /run/NetworkManager/, /run/nscd/).
It deliberately does not exempt all of /run, because /run/user/<uid> holds the keyring, gnupg
and ssh-agent sockets. A resolver reading from somewhere outside those will have those reads
denied; the audit log names every path refused. Note also that the exemption is read-only - a
write into a system path is still refused - and that the boundary covers the filesystem only, so
network and process spawn are unaffected.
grith: command not found after installing
The installer puts the binary in ~/.local/bin unless you passed --global. Add it to PATH.
Getting help
- GitHub Discussions for questions.
- GitHub Issues for confirmed bugs.
- Responsible disclosure for anything security-sensitive. Please do not open a public issue.