xorcise doctor checks this host’s prerequisites and prints an exact fix per failure, and xorcise status probes the REST plane, the OTLP plane, and the Docker daemon.
Find your problem
Startup problems
Cannot connect to the Docker daemon
Cannot connect to the Docker daemon
xorcise up is real by default and needs a reachable Docker daemon.Fix. Start Docker — sudo systemctl start docker on Linux, or open Docker Desktop on macOS — and run up again. To look around without Docker, xorcise up --stub boots a demo in which missions do not execute.permission denied while trying to connect to the Docker daemon socket
permission denied while trying to connect to the Docker daemon socket
docker group. This is the standard fresh-Ubuntu case and it is not a XORCISE problem.Fix. Add yourself to the group, then start a new login session:newgrp docker is not enough — it changes only the shell you type it into, so xorcise up in any other terminal keeps failing.docker compose is reported missing
docker compose is reported missing
docker compose. The legacy standalone docker-compose v1 binary does not satisfy it, so a host with only v1 installed fails this check while docker-compose --version looks fine.Fix. Install the plugin:docker-compose-plugin package works equally well. Confirm with docker compose version.openssl is reported missing
openssl is reported missing
openssl is a hard prerequisite. XORCISE uses it to generate the private certificate authority and TLS certificate for the local Headscale control plane, so without it no run can get a network.Fix. Install it — sudo apt install openssl — and re-run xorcise doctor to confirm.port 3001 (rest) is busy — using 3002 instead
port 3001 (rest) is busy — using 3002 instead
up prints. Other XORCISE commands find the relocated brain by themselves. If you need a fixed port, pin it before starting with xorcise up --port 3010, or set rest_port in ~/.xorcise/config.toml. A port genuinely held by a foreign process is reported differently, naming the port and plane, and needs that process stopped.already running — UI at http://127.0.0.1:3001/ui
already running — UI at http://127.0.0.1:3001/ui
xorcise up against a running instance is success and exits 0 — that is deliberate, so scripts and agents can re-run it defensively. You do not need xorcise down first, and there is no restart to perform. If the previous process exited uncleanly, up clears the stale record and continues on its own.database is behind the schema — run 'xorcise db upgrade' first
database is behind the schema — run 'xorcise db upgrade' first
xorcise up again. The same status is visible on Settings → Environment, which reads behind — migration needed.migration history mismatch
migration history mismatch
~/.xorcise/xorcise.db first. Then either install the build that created it and upgrade from there, or re-initialise with xorcise down --purge, which destroys all local data. There is no downgrade path.XORCISE did not become healthy in 10s
XORCISE did not become healthy in 10s
~/.xorcise/serve.log — the brain’s stderr goes there, and it is truncated on every up, so the traceback you want is the one at the top. ~/.xorcise/logs/ is created but empty; nothing writes to it, and it will not help you here. Running xorcise serve in the foreground reproduces the failure directly, and xorcise doctor re-checks the prerequisites.The web UI loads blank or unstyled
The web UI loads blank or unstyled
/ui is stale or half-built. This only happens in a source checkout — an installed package ships the built UI.Fix. Confirm the brain is healthy with xorcise status and reprint the address with xorcise ui. up rebuilds the UI automatically when it needs to, so if the page is still broken, read ~/.xorcise/frontend-build.log for what the build said.Run and telemetry problems
The run sits on 'Action required — start your agent' or 'Awaiting agent'
The run sits on 'Action required — start your agent' or 'Awaiting agent'
xorcise run launch-cmd <run_id> — and check the entries below. If the fact strip shows the environment as Starting, wait for Ready before launching: an agent that joins early ends up on a tailnet whose targets do not exist yet.No traces arrive at all
No traces arrive at all
host.docker.internal into the telemetry endpoint, and a plain terminal cannot resolve that name — the exporter fails silently and not one span arrives.Fix. Ask for the mode that matches where the agent actually runs:--add-host host.docker.internal:host-gateway instead.Two other causes account for most of the rest. A bare KEY=VALUE paste is not inherited by the child process — use set -a; source launch.env; set +a, or paste the single launch block, which already does that. And xorcise run launch-profile printing nothing at all means no collector host is configured for this run.partialSuccess.rejectedSpans in the exporter's response
partialSuccess.rejectedSpans in the exporter's response
…or run is sealed, and it is the definitive signal for this class of problem. Rejected batches are dropped, never blended into another run.Fix. Work down these in order.xorcise.run_idwas set as a span attribute. Only the resource attribute correlates; set it throughOTEL_RESOURCE_ATTRIBUTES.- You already exported
OTEL_RESOURCE_ATTRIBUTESand overwrote it. Appendxorcise.run_id=<id>comma-separated instead. - The prompt’s
xorcise.run_id=<id>marker line was deleted. For a harness with no telemetry provider that marker is the only correlation channel there is. - The run is already terminal. XORCISE keeps ingestion open for a few seconds after a run seals and rejects everything after that, by design. Start a new run rather than trying to backfill.
- The prompt was copied from an earlier run, so the marker names that run.
Spans arrived but the replay is empty
Spans arrived but the replay is empty
The agent joined the tailnet but cannot reach a target
The agent joined the tailnet but cannot reach a target
$XORCISE_SOCKS5 in the sourceable env file it writes. Do not hardcode a port, and configure the proxy explicitly in tools like pwntools rather than assuming a direct connection.The environment never becomes Ready
The environment never becomes Ready
deploy_failed. A run that ends this way records a normal-looking, near-zero result that is not flagged partial — check the trigger before concluding the agent performed badly.Fix. Read the environment chip’s tooltip on the live page for the brain’s own detail. A mission that builds or pulls a multi-gigabyte image the first time can genuinely exceed the window; run it again once the image is local. If it fails repeatedly, the mission’s compose file is the place to look.Grading problems
The result says the judge did not run
The result says the judge did not run
judge_status reads model-not-configured: no judge model is set, so XORCISE never called one. The judge half scored 0.0, and because that zero is still multiplied by 0.5, the run’s ceiling was 50%. A score of 42.5% here is half a score, not a failed agent.Fix. Configure a judge model — see Configuration — then re-evaluate the run. Re-grading replays the already-sealed evidence against your current settings. Do not run the agent again; nothing about the run needs to change.The judge failed on a long run
The judge failed on a long run
judge_status reads unavailable and judge_detail carries the provider’s own message, usually about context length. A long lab run produces an enormous transcript — a measured ten-minute run produced a 369,000-token prompt against a 272,000-token ceiling — and when the call cannot be made, the score degrades to deterministic-only.Fix. Lower the per-span cap, which defaults to 2000 tokens and trims each span to a head-and-tail window while keeping every action:--transcript-max-tokens 0 to switch it back off and let the provider’s real limit be the gate.The result reads 'grading' instead of a score
The result reads 'grading' instead of a score
xorcise run status <run_id> re-checks from the terminal. Polling also re-drives grading that was lost to a restart, so a run stuck in this state past the judge’s timeout usually resolves by being asked once more.Mission and library problems
xorcise mission list, install one with xorcise mission pull <id>, or use the Missions page. xorcise mission ingest is a stub that prints the coming-soon message and installs nothing, whatever arguments you give it, and the Ingest a bundle button on the Missions page opens a product preview rather than a file picker. The manifest rules below describe the format that feature will accept, so you can prepare bundles now — but nothing in this release installs a mission from a local bundle.Library missions do not appear
Library missions do not appear
xorcise catalog connect, or the XORCISE Remote switch on the Settings page. The library needs no API key, account, or sign-in, so a missing credential is never the cause here.A pull sits at 0 bytes
A pull sits at 0 bytes
3 — the pull is still running on the server.What a valid mission.json must satisfy
What a valid mission.json must satisfy
metadata.type is required and accepts only lab or static — the older genre labels such as ctf are dead. A lab mission requires an environment block, a static mission requires at least one attachment, and check weights must either all be declared and sum to 1.0 or all be omitted.Reading a validation error. A manifest that breaks any of those rules fails as ingest failed: invalid mission.json, and the messages are literal — they name the field path, for example invalid mission.json: checks.0. Compare that field against Mission manifest, which is the authoritative shape. Missions installed with xorcise mission pull are already valid, so nothing you install today can fail these rules.Exit codes in scripts
XORCISE uses five exit codes:0 success, 1 runtime failure, 2 usage error, 3 operation still in progress, and 130 interrupted.
3 is the one that breaks naive automation. run status, run report, run terminate --wait, and mission pull return it when the work is still running server-side. A CI gate that treats every non-zero code as a failure reads a perfectly healthy in-progress run as broken. Poll until you get 0.0 also covers idempotent no-ops: up when already running, mission pull when the mission is already installed, and catalog connect when already connected. --json is available on 19 commands, and run status --json is always parseable because its envelope carries a status of active or grading rather than a score.
Start clean
When you want to discard everything and begin again:~/.xorcise. Run it before pip uninstall xorcise if you are removing XORCISE entirely — the purge is what cleans up the Docker resources, and once the package is gone nothing knows how to find them.
File a useful bug report
Include five things and most reports become reproducible immediately: the output ofxorcise --version, the full output of xorcise doctor, the run id if a run is involved, the exact message you saw rather than a paraphrase of it, and the last few lines of ~/.xorcise/serve.log when the brain failed to start. If XORCISE printed unexpected error: … — re-run with XORCISE_DEBUG=1 for the full traceback, do that and attach the traceback.