Exit codes & errors

What CLI exit codes mean, what gRPC status codes you'll see, and how to debug each.

CLI exit codes

CodeMeaning
0Success.
1Generic failure (network, parse, validation).
2Usage error — bad flag, missing argument.
3Auth failure — Unauthenticated or PermissionDenied.
4Resource not found.
5Conflict / already exists.
6Validation error.
7Timeout (rollout, scale, etc.).
124Inner-process timeout (passed through from exec).

Scripts should branch on exit code — not on stderr text.

gRPC status codes

The CLI surfaces these directly:

CodeWhenCommon fix
UnauthenticatedNo token, expired token, or revoked token.rune login again.
PermissionDeniedToken is valid but the policy doesn't allow this verb/resource.Check rune whoami policies; ask admin.
NotFoundResource missing.rune get to confirm.
AlreadyExistsTrying to create something that already exists.Use cast (idempotent) instead of create.
InvalidArgumentSchema/validation rejected by the server.rune lint locally first.
FailedPreconditionState doesn't allow this op (e.g., delete in use).Resolve dependents first.
DeadlineExceededRequest timed out.Increase --timeout, check server load.
InternalServer-side bug or runtime error.Check runed logs.
UnavailableServer unreachable.Network / process / firewall.

Common error messages and fixes

failed to connect to API server

The server isn't reachable. Check:

sudo systemctl status runed
sudo journalctl -u runed -n 50 --no-pager
nc -zv <host> 7863

If TLS is enabled, make sure the client context has the right CA / cert / key.

missing bearer token

Your context has no token. Re-run rune login or set --token / --token-file for a one-off.

invalid bearer token

The token is wrong, expired, or revoked. rune admin token list to verify.

access denied for resource: X verb: Y

RBAC. Your subject's policies don't allow Y on X. Either:

  • Use a different context with broader policies, or
  • Get an admin to attach a policy. See Identity & RBAC.

validation error: <field>: ...

The spec failed validation. Fix the field. rune lint would have caught this locally.

service ... has dependents

Something depends on the resource you're deleting. List dependents:

rune deps dependents <name>

Force if you really mean it:

rune delete <name> --force

failed to pull image: ...

The Docker runner couldn't pull. Either:

  • Image doesn't exist (typo).
  • Registry is private — add credentials with rune admin registry add.
  • Network can't reach the registry from the host.

An authentication failure is annotated with which registry pattern was involved — see the two entries below.

no [[docker.registries]] entry matches <image>

The registry demanded credentials and the pull went out without one. The message names the most common reason, but it fires whenever no credential was sent, which has three causes:

  • No entry's registry pattern matched the image — usually a pattern scoped past the repository. Widen it, or add an entry.
  • An entry matched but declares type: none, so it deliberately sends nothing. The image is not public after all; give that entry a real credential — do not just delete it, or the image falls through to a broader pattern.
  • The service sets imagePullAnonymous: true, which skips pattern matching entirely.

Rule out the last two before widening a pattern. See docker.registries[].

the credential configured for registry pattern "X" was rejected

A credential was sent and the registry refused it. Either renew it, or — if the image is public and only inherited the credential from a broader pattern — scope the pattern to your private repositories, add a type: none entry for the public path, or set imagePullAnonymous: true on the service.

If rune admin registry list shows no entry for X, the credential was ambient — the runed user's ~/.docker/config.json or a cloud metadata service account. Those carry no pattern, so the message falls back to naming the image's host. Fix the ambient source, or set docker.disable_ambient_registry_auth in the runefile.

volume <ns>/<name> not yet mounted on node <node>

The instance is waiting for the agent to attach and mount its volume. The two forms are alternatives, not a prefix and a suffix: when the agent has a cause to report it replaces (will retry) with that cause, wrappers and all —

volume prod/pgdata not yet mounted on node node-abc: agent.volumes:
attach prod/pgdata: dovolume: getVolume <handle>: storage driver:
provider rejected credentials: GET /v2/volumes/<id> -> HTTP 401: … 
(check the storage class's apiToken)

— and the bare (will retry) form just means no cause was available yet. Read the cause, not the absence of (will retry): the wording is dropped for any cause, transient or not. The agent keeps retrying regardless, so a rejected credential leaves the instance blocked until you renew it. See Persistent storage.

restart cannot proceed: <instance> (Stalled) never got a container

The instance holding the slot exhausted its create attempts and the replacement can't be created. Read the reason from rune describe service <name>, fix it, and run rune restart again. See Recovering instances stuck in create.

failed to start process: exec: "...": file does not exist

Process runner can't find the binary. The path in process.command must exist on the host.

Where to look for more

  • runed logs: journalctl -u runed -n 200 --no-pager.
  • Set --log-level=debug on the CLI for verbose RPC traces.
  • Set --debug on runed for full server traces.
  • Each RPC error includes a server-side request ID — search for it in the logs.