Exit codes
Every exit code the engine knows, its text and telemetry category, and how to read an error line.
When a script fails it prints one line with an exit code and an explanation.
The texts come from explain_exit_code in
api/exitcodes.func;
the line itself is printed by error_handler in
core/error_handler.func.
The same file is loaded on the host (through api/api.func) and inside the
container (by lxc/install.func), so both sides use one table.
Reading an error line
✖️ in line 24: exit code 100 (APT: Package manager error (broken packages / dependency problems)): while executing command apt install -y build-essential| Part | Meaning |
|---|---|
in line 24 | Line that was running. For an install script the number is one higher than the line in install/<app>-install.sh |
exit code 100 | Exit status of the failing command |
(…) | Explanation, from the table below or adjusted to the command (next section) |
while executing command … | The command that failed |
Below that line you get the output of the failing command, hints for known causes, and on the host the path of the full log. When the install inside a container fails, the host prints its own summary instead:
✖️ Installation failed in container 105 (exit code: 100)
📋 Installation log: /tmp/vaultwarden-105-1a2b3c4d.log
Error: APT: Package manager error (broken packages / dependency problems)followed by the recovery menu. The exit code of the whole run is the code shown.
The explanation depends on the command
Many programs use the same small numbers for different things. The handler therefore only uses a table text that belongs to a tool family when a tool of that family ran:
| Table prefix | Applies when the command runs |
|---|---|
curl: | curl |
APT:, DPKG: | apt, apt-get, apt-cache, aptitude, dpkg, dpkg-query, dpkg-reconfigure |
Node.js:, npm/Node.js:, npm/pnpm/yarn: | node, npm, npx, pnpm, yarn, corepack, bun |
Python: | python, python3, pip, pip3, pipx, uv, uvx |
PostgreSQL: | psql, pg_*, postgres |
MySQL/MariaDB: | mysql, mariadb, mysqladmin, mariadb-admin |
MongoDB: | mongosh, mongo, mongod |
Systemd: | systemctl |
git: | git |
For any other program the line reads <program> exited with status N. The
same wording is used for exit 1, 2 and 3 whenever the program is known, and a
few shell cases get their own text: Arithmetic expression evaluated to 0,
Test condition was false, Command substitution exited with status N,
grep found no match, Systemd: unit not found (exit 5 from systemctl) and
Exit status N for a bare return or exit.
A code that is not in the table is shown as Unknown error.
Categories
categorize_error assigns each failure a category for telemetry. The category
column below is what it returns for the code alone. Three things take
precedence, in this order:
ERROR_CATEGORY_OVERRIDE, which the host sets todependency,resource,networkorstoragewhen an install failed with exit 1 and the output shows an APT, out-of-memory, network or disk-full error.- The codes that are always
user_aborted(113, 114, 122, 129, 130, 143, 253, 254),resource(134, 137) orsignal(139, 141). - The program that failed:
systemctlgivesservice;pct,qm,pvesm,pveshandpveamgiveproxmox.
| Category | Meaning |
|---|---|
user_aborted | You cancelled, declined a prompt, or the run was interrupted |
network | DNS, connection, HTTP or TLS failure |
timeout | A command or a lock wait ran out of time |
storage | Not enough space, or a storage that cannot hold containers |
dependency | Package manager failure or a missing command |
permission | A command could not be executed or was refused |
config | Invalid settings or input |
proxmox | Container, template or cluster operation failed |
service | A service did not start or a build failed |
database | Database connection, authentication or query failure |
runtime | Node.js runtime failure |
resource | Killed or aborted, usually out of memory |
signal | Segmentation fault or broken pipe |
shell | Generic exit 1 or 2 |
unknown | Everything else |
The table
All 167 codes that explain_exit_code knows, grouped as in the source.
Generic and shell
| Code | Text | Category |
|---|---|---|
| 0 | Cancelled before completion (no error) | unknown |
| 1 | General error | shell |
| 2 | Invalid usage or arguments | shell |
| 3 | Command-specific error | unknown |
| 10 | Docker / privileged mode required (unsupported environment) | config |
curl and wget
| Code | Text | Category |
|---|---|---|
| 4 | curl: Feature not supported or protocol error | unknown |
| 5 | curl: Could not resolve proxy | unknown |
| 6 | curl: DNS resolution failed (could not resolve host) | network |
| 7 | curl: Failed to connect (network unreachable / host down) | network |
| 8 | curl: Server reply error (FTP/SFTP or apk untrusted key) | unknown |
| 16 | curl: HTTP/2 framing layer error | unknown |
| 18 | curl: Partial file (transfer not completed) | unknown |
| 22 | curl: HTTP error returned (404, 429, 500+) | network |
| 23 | curl: Write error (disk full or permissions) | unknown |
| 24 | curl: Write to local file failed | unknown |
| 25 | curl: Upload failed | unknown |
| 26 | curl: Read error on local file (I/O) | unknown |
| 27 | curl: Out of memory (memory allocation failed) | unknown |
| 28 | curl: Operation timeout (network slow or server not responding) | timeout |
| 30 | curl: FTP port command failed | unknown |
| 32 | curl: FTP SIZE command failed | unknown |
| 33 | curl: HTTP range error | unknown |
| 34 | curl: HTTP post error | unknown |
| 35 | curl: SSL/TLS handshake failed (certificate error) | network |
| 36 | curl: FTP bad download resume | unknown |
| 39 | curl: LDAP search failed | unknown |
| 44 | curl: Internal error (bad function call order) | unknown |
| 45 | curl: Interface error (failed to bind to specified interface) | unknown |
| 46 | curl: Bad password entered | unknown |
| 47 | curl: Too many redirects | unknown |
| 48 | curl: Unknown command line option specified | unknown |
| 51 | curl: SSL peer certificate or SSH host key verification failed | unknown |
| 52 | curl: Empty reply from server (got nothing) | unknown |
| 55 | curl: Failed sending network data | unknown |
| 56 | curl: Receive error (connection reset by peer) | unknown |
| 57 | curl: Unrecoverable poll/select error (system I/O failure) | unknown |
| 59 | curl: Couldn't use specified SSL cipher | unknown |
| 61 | curl: Bad/unrecognized transfer encoding | unknown |
| 63 | curl: Maximum file size exceeded | unknown |
| 75 | Temporary failure (retry later) | unknown |
| 78 | curl: Remote file not found (404 on FTP/file) | unknown |
| 79 | curl: SSH session error (key exchange/auth failed) | unknown |
| 92 | curl: HTTP/2 stream error (protocol violation) | unknown |
| 95 | curl: HTTP/3 layer error | unknown |
BSD sysexits
| Code | Text | Category |
|---|---|---|
| 64 | Missing or invalid input (a required setting was not given) | config |
| 65 | Data format error (bad input data) | unknown |
| 66 | Input file not found (cannot open input) | unknown |
| 67 | User not found (addressee unknown) | unknown |
| 68 | Host not found (hostname unknown) | unknown |
| 69 | Service unavailable | unknown |
| 70 | Internal software error | unknown |
| 71 | System error (OS-level failure) | unknown |
| 72 | Critical OS file missing | unknown |
| 73 | Cannot create output file | unknown |
| 74 | I/O error | unknown |
| 76 | Remote protocol error | unknown |
| 77 | Permission denied | unknown |
APT and dpkg
| Code | Text | Category |
|---|---|---|
| 100 | APT: Package manager error (broken packages / dependency problems) | dependency |
| 101 | APT: Configuration error (bad sources.list, malformed config) | dependency |
| 102 | APT: Lock held by another process (dpkg/apt still running) | dependency |
| 255 | DPKG: Fatal internal error | dependency |
Validation and setup (103–123)
| Code | Text | Category |
|---|---|---|
| 103 | Validation: Shell is not Bash | unknown |
| 104 | Validation: Not running as root (or invoked via sudo) | unknown |
| 105 | Validation: Proxmox VE version not supported | unknown |
| 106 | Validation: Unsupported architecture (requires amd64 or arm64) | unknown |
| 107 | Validation: Kernel key parameters unreadable | unknown |
| 108 | Validation: Kernel key limits exceeded | unknown |
| 109 | Proxmox: No available container ID after max attempts | unknown |
| 110 | Proxmox: Failed to apply default.vars | unknown |
| 111 | Proxmox: App defaults file not available | unknown |
| 112 | Proxmox: Invalid install menu option | unknown |
| 113 | LXC: Under-provisioned — user aborted update | user_aborted |
| 114 | LXC: Storage too low — user aborted update | user_aborted |
| 115 | Download failed (engine, install script or VM image) | unknown |
| 116 | Proxmox: Default bridge vmbr0 not found | unknown |
| 117 | LXC: Container did not reach running state | unknown |
| 118 | LXC: No IP assigned to container after timeout | unknown |
| 119 | Proxmox: No valid storage for rootdir content | unknown |
| 120 | Proxmox: No valid storage for vztmpl content | unknown |
| 121 | LXC: Container network not ready (no IP after retries) | unknown |
| 122 | LXC: No internet connectivity — user declined to continue | user_aborted |
| 123 | LXC: Local IP detection failed | unknown |
Shell and signals (124–146)
| Code | Text | Category |
|---|---|---|
| 124 | Command timed out (timeout command) | timeout |
| 125 | Command failed to start (Docker daemon or execution error) | unknown |
| 126 | Command invoked cannot execute (permission problem?) | permission |
| 127 | Command not found | dependency |
| 128 | git: Fatal error (repository, network or permission problem) | config |
| 129 | Killed by SIGHUP (terminal closed / hangup) | user_aborted |
| 130 | Aborted by user (SIGINT) | user_aborted |
| 131 | Killed by SIGQUIT (core dumped) | unknown |
| 132 | Killed by SIGILL (illegal CPU instruction) | unknown |
| 134 | Process aborted (SIGABRT - possibly Node.js heap overflow) | resource |
| 137 | Killed (SIGKILL / Out of memory?) | resource |
| 139 | Segmentation fault (core dumped) | signal |
| 141 | Broken pipe (SIGPIPE - output closed prematurely) | signal |
| 143 | Terminated (SIGTERM) | user_aborted |
| 144 | Killed by signal 16 (SIGUSR1 / SIGSTKFLT) | unknown |
| 146 | Killed by signal 18 (SIGTSTP) | unknown |
Services and builds (150–154)
| Code | Text | Category |
|---|---|---|
| 150 | Systemd: Service failed to start | service |
| 151 | Systemd: Service unit not found | service |
| 152 | Permission denied (EACCES) | permission |
| 153 | Build/compile failed (make/gcc/cmake) | service |
| 154 | Node.js: Native addon build failed (node-gyp) | service |
Python (160–162)
| Code | Text | Category |
|---|---|---|
| 160 | Python: Virtualenv / uv environment missing or broken | dependency |
| 161 | Python: Dependency resolution failed | dependency |
| 162 | Python: Installation aborted (permissions or EXTERNALLY-MANAGED) | dependency |
PostgreSQL (170–173)
| Code | Text | Category |
|---|---|---|
| 170 | PostgreSQL: Connection failed (server not running / wrong socket) | database |
| 171 | PostgreSQL: Authentication failed (bad user/password) | database |
| 172 | PostgreSQL: Database does not exist | database |
| 173 | PostgreSQL: Fatal error in query / syntax | database |
MySQL and MariaDB (180–183)
| Code | Text | Category |
|---|---|---|
| 180 | MySQL/MariaDB: Connection failed (server not running / wrong socket) | database |
| 181 | MySQL/MariaDB: Authentication failed (bad user/password) | database |
| 182 | MySQL/MariaDB: Database does not exist | database |
| 183 | MySQL/MariaDB: Fatal error in query / syntax | database |
MongoDB (190–193)
| Code | Text | Category |
|---|---|---|
| 190 | MongoDB: Connection failed (server not running) | database |
| 191 | MongoDB: Authentication failed (bad user/password) | database |
| 192 | MongoDB: Database not found | database |
| 193 | MongoDB: Fatal query error | database |
Engine (199)
| Code | Text | Category |
|---|---|---|
| 199 | Engine: exit code not reported | unknown |
Proxmox VE and Incus host (200–231)
| Code | Text | Category |
|---|---|---|
| 200 | Proxmox: Failed to create lock file | proxmox |
| 203 | Proxmox: Missing CTID variable | config |
| 204 | Proxmox: Missing PCT_OSTYPE variable | config |
| 205 | Proxmox: Invalid CTID (<100) | config |
| 206 | Proxmox: CTID already in use | config |
| 207 | Proxmox: Password contains unescaped special characters | config |
| 208 | Proxmox: Invalid container settings (network, DNS, RAM, password, mounts) | config |
| 209 | Proxmox: Container creation failed | proxmox |
| 210 | Proxmox: Cluster not quorate | proxmox |
| 211 | Proxmox: Timeout waiting for template lock | timeout |
| 212 | Proxmox: Storage type 'iscsidirect' does not support containers (VMs only) | proxmox |
| 213 | Proxmox: Storage type does not support 'rootdir' content | proxmox |
| 214 | Proxmox: Not enough storage space | storage |
| 215 | Proxmox: Container created but not listed (ghost state) | proxmox |
| 216 | Proxmox: RootFS entry missing in config | proxmox |
| 217 | Proxmox: Storage not accessible | storage |
| 218 | Proxmox: Template file corrupted or incomplete | proxmox |
| 219 | Proxmox: CephFS does not support containers - use RBD | storage |
| 220 | Proxmox: Unable to resolve template path | proxmox |
| 221 | Proxmox: Template file not readable | proxmox |
| 222 | Proxmox: Template download failed | proxmox |
| 223 | Proxmox: Template not available after download | proxmox |
| 224 | Proxmox: PBS storage is for backups only | storage |
| 225 | Proxmox: No template available for OS/Version | proxmox |
| 226 | Proxmox: VM disk import or post-creation setup failed | unknown |
| 227 | Proxmox: Container created but failed to start | proxmox |
| 228 | Proxmox: Cluster filesystem /etc/pve not available | proxmox |
| 229 | Incus: Project restrictions forbid a config the container needs | permission |
| 231 | Proxmox: LXC stack too old for the template, or its upgrade failed | proxmox |
Tools and add-ons (232–238)
| Code | Text | Category |
|---|---|---|
| 232 | Tools: Wrong execution environment (run on PVE host, not inside LXC) | unknown |
| 233 | Tools: Application not installed (update prerequisite missing) | unknown |
| 234 | Tools: No LXC containers found or available | unknown |
| 235 | Tools: Backup or restore operation failed | unknown |
| 236 | Tools: Required hardware not detected | unknown |
| 237 | Tools: Dependency package installation failed | unknown |
| 238 | Tools: OS or distribution not supported for this addon | unknown |
Node.js (239–249)
| Code | Text | Category |
|---|---|---|
| 239 | npm/Node.js: Unexpected runtime error or dependency failure | unknown |
| 243 | Node.js: Out of memory (JavaScript heap out of memory) | runtime |
| 245 | Node.js: Invalid command-line option | runtime |
| 246 | Node.js: Internal JavaScript Parse Error | runtime |
| 247 | Node.js: Fatal internal error | runtime |
| 248 | Node.js: Invalid C++ addon / N-API failure | runtime |
| 249 | npm/pnpm/yarn: Unknown fatal error | runtime |
Application install and update (250–254)
| Code | Text | Category |
|---|---|---|
| 250 | App: Download failed or version not determined | unknown |
| 251 | App: File extraction failed (corrupt or incomplete archive) | unknown |
| 252 | App: Required file or resource not found | unknown |
| 253 | App: Data migration required — update aborted | user_aborted |
| 254 | App: User declined prompt or input timed out | user_aborted |
Notes on individual codes
| Code | Note |
|---|---|
| 0 | Only shown when a run ended without an error but also without finishing, for example after cancelling a dialog. Telemetry records it as aborted |
| 1 | An unsupported Proxmox VE version ends container scripts with exit 1 (pve_check). Code 105 is used by the VM path |
| 10 | The host adds a hint that the container probably needs privileged mode or nesting |
| 101 | APT: text only for apt/dpkg commands; cargo exits 101 on a panic and is reported as cargo exited with status 101 |
| 115 | The engine could not download one of its own files or the install script. For a fork, set COMMUNITY_SCRIPTS_URL, see Loading |
| 127 | The handler names the missing command when it can identify it |
| 129 | A closed console does not end a run by itself, see Error handling |
| 130, 143 | Set by the signal handlers for Ctrl-C and SIGTERM |
| 134, 137, 243 | The recovery menu offers a rebuild with more RAM and CPU |
| 199 | Used when no numeric exit code reached the host, for example when the container stopped by itself during the install |
| 210, 228 | Raised by pve_check before any dialog opens |
| 254 | Also used by confirm_external_installer when the upstream installer is declined |
Using exit codes in a script
Let commands fail with their own status. When your script decides to stop,
print the reason and exit with the code from the table that describes it, as
ct/endurain.sh
does in its update function:
if [[ ! -d /opt/endurain ]]; then
msg_error "No ${APP} installation found!"
exit 233
fiDo not invent new numbers and do not copy this table into a script. Codes are
added to api/exitcodes.func in the engine, and this page follows that file.