Exit codes
| Code | Class | Meaning | Stable slugs |
|---|---|---|---|
| 0 | ok | success | — |
| 1 | internal | unexpected failure — report as a bug | internal |
| 2 | usage | usage error (rendered by clap), destructive op without --yes, JVM profiling without --i-accept-the-risk, an invalid import file, an unreadable command input, a raw api call the gateway rejected with an unclassified 4xx (body carried verbatim), a declared deploy tree that fails render validation or carries an embedded secret, or a deploy apply of a destructive or drifted plan without its flag | confirmation_required, profiling_risk_not_accepted, invalid_import_file, invalid_input, gateway_client_error (P9), deploy_tree_invalid, embedded_secret, destructive_change_refused |
| 3 | config | local configuration problem | profile_not_found, no_active_profile, secret_unavailable, password_unavailable, config_invalid, poll_interval_too_small, module_not_registered |
| 4 | network | gateway, or a module release feed, unreachable / timeout / TLS, or a deploy host transport failure (an unreadable gateway data directory or a hostile live tree) | network_error, module_feed_unreachable, transport_failed |
| 5 | auth | gateway rejected credentials | auth_rejected |
| 6 | target_state | command invalid for the gateway's current state, a module artifact the feed refused to serve or verify, a held config scan-lock, a resource write refused for its signature, a create naming a resource or mode that already exists, an unusable on-box deploy declared-names ledger, a deploy plan that changed since it was reviewed, a deploy removal a core copy shadows, a failed apply preflight, an interrupted deploy's journal still on the box, live files a rollback would overwrite, an unusable deploy run record, a rollback that could not restore, a project the git module still manages (.git present), a project whose parent is missing, cyclic or not inheritable, or an artifact whose hash is not the one that was reviewed | gateway_too_old, gateway_not_commissioned, gateway_restarting, not_found, project_exists, resource_binary, trial_not_expired, provider_not_found, routes_not_deployed, webdev_unlicensed, route_version_mismatch, webdev_route_error, tag_collision, alarm_journal_missing, import_denied, session_not_prunable, eam_not_controller, eam_task_type_refused, eam_task_in_flight, script_exec_not_configured, lint_tool_absent, node_tool_absent, provider_root_unsupported, bundle_not_available, module_release_not_found, module_digest_mismatch, module_feed_unusable, module_digest_changed, module_uninstall_denied, scan_lock_held, resource_signature_rejected, resource_exists, mode_exists, deploy_ledger_invalid, plan_stale, deploy_blocked, deploy_preflight_failed, deploy_journal_present, deploy_live_changed, deploy_run_invalid, rollback_failed, project_git_managed, project_parent_invalid, project_hash_mismatch |
| 7 | rig | docker/compose rig failure (discovery, lifecycle, port conflicts) | rig_error |
The exit-code table lives in exactly two places — this README and
CoreError::exit_code() in crates/ignition-core/src/error.rs — kept in
sync by two tests: exit_code_mapping_enumerated pins the enum to its
exit-code/slug literals, and readme_exit_table_agreement parses THIS
table via include_str! and cross-checks every slug ↔ exit-code row
against those literals in both directions, so a missing, stale, or
misplaced table row fails the test suite (the Three-Place rule: enum +
literals + this table, all machine-checked).
ign api call partitions gateway answers through the same classifier:
401/403 → 5 auth_rejected, 404 → 6 not_found, 503 → 6
gateway_restarting, 500 → 1 internal, and every OTHER 4xx → 2
gateway_client_error with the response body carried verbatim in the
message (4 KiB cap, ... [truncated] marker). Usage-class input
problems (auth-pattern headers, bad --path, malformed
--header/--query) refuse exit 2 invalid_input BEFORE any
resolution — the envelope's profile is null and zero requests hit
the gateway.