Skip to content

We use analytics cookies to see how the site is used. They are only set if you accept. Accepting also turns on session recording (pages viewed, clicks and scrolls) so we can fix problems; what you type stays hidden. It also lets Meta (Facebook) see your visit, so we can measure our ads. Read the privacy policy

A lift floor display reading 137 above a steel panel of round buttons numbered 0, 1, 2, 126, 127, 130, 137, 143 and 255.

Floor directory · 8 min read

Exit Codes 0 to 255: What 1, 2, 126, 127, 130 and 137 Mean, and Which One Your CLI Should Return

Every process hands back one number when it ends. Here is what each common exit code means, a command that reproduces it, why 137 turns up in containers, and which codes to use in your own tool.

An exit code is a single number from 0 to 255 that a finished process hands back to whatever started it: 0 means it worked, anything else means it did not. In a shell the number of the last command sits in $?. The rest of this page takes the codes you will meet most, lowest floor first, with the rule behind each one and a command that reproduces it. Every command was run in Bash 3.2 on macOS on 11 November 2026, and every rule links to the document it comes from. Other shells word their error lines differently; the numbers are the same.

The floor guide: what each exit code means

Exit code 0: success

The Bash manual puts it in one line: a command that exits with a zero status has succeeded, and a non-zero status means failure. It also says why the scheme looks upside down: there is one way to say success and many ways to say what went wrong.

true; echo $?
0

Exit code 1: it failed, and that is all you know

No standard gives 1 a meaning beyond "not zero". Most programs use it as the catch-all failure. Some give it a narrower meaning of their own: GNU grep exits 1 when no line was selected, which is an answer, not a fault. Read the tool's manual before treating 1 as an error.

echo hello | grep -q goodbye; echo $?
1

Exit code 2: often a usage error

The Bash manual says all Bash builtins return 2 "to indicate incorrect usage, generally invalid options or missing arguments". Many other tools copy the habit, but it is a habit, not a rule. grep uses 2 for a real error such as an unreadable file.

grep hello /no/such/file; echo $?
grep: /no/such/file: No such file or directory
2

Exit code 126: found, but cannot be run

This one is standard. POSIX, section 2.8.2, says that when the command name is found but is not an executable utility, the exit status shall be 126. The usual cause is a script without the execute bit, so the fix is usually chmod +x.

sh -c /etc/hosts; echo $?
sh: /etc/hosts: Permission denied
126

Exit code 127: command not found

Also from POSIX: "If the command is not found, the exit status shall be 127." In CI it almost always means a tool is not installed in the image, or is not on PATH for that step. The program you meant to run never started.

sh -c no-such-command; echo $?
sh: no-such-command: command not found
127

Exit codes above 128: killed by a signal

A process killed by a signal never chose a code. The shell makes one up. POSIX only requires it to be greater than 128. Bash is exact: for a fatal signal number N it reports 128+N. So 130 is signal 2, the Ctrl-C interrupt, and 137 is signal 9, SIGKILL.

sh -c 'kill -INT $$'; echo $?
130
sh -c 'kill -KILL $$'; echo $?
137

Your shell may print a line such as "Killed: 9" before the number.

Exit code 255: the top floor, and what happens above it

A shell sees one byte of the status. POSIX says only the least significant 8 bits of the value (status & 0377) are available through wait() and waitpid(), the calls a shell uses to collect it. So a program that exits with -1 shows up as 255, and one that exits with 256 shows up as 0, which every caller reads as success.

bash -c 'exit -1'; echo $?
255
bash -c 'exit 256'; echo $?
0
bash -c 'exit 300'; echo $?
44

255 is also what ssh returns when ssh itself failed, as opposed to the remote command.

Signal exit codes: 128 plus the signal number

These are the sums you are most likely to see. The signal numbers come from the Linux signal(7) page, where these eight have the same number on every architecture it lists.

Exit codeSumSignalWhat signal(7) calls it
129128 + 1SIGHUPHangup detected on controlling terminal or death of controlling process
130128 + 2SIGINTInterrupt from keyboard
131128 + 3SIGQUITQuit from keyboard
134128 + 6SIGABRTAbort signal from abort(3)
137128 + 9SIGKILLKill signal
139128 + 11SIGSEGVInvalid memory reference
141128 + 13SIGPIPEBroken pipe: write to pipe with no readers
143128 + 15SIGTERMTermination signal

You do not have to do the subtraction. Bash's kill builtin accepts an exit status after -l and prints the signal behind it:

kill -l 137
KILL

Why does exit code 137 show up in Docker and Kubernetes?

Unless a program picked the number itself, 137 says one thing: the process received SIGKILL. It does not say who sent it. Three senders are common, and each needs a different fix.

  • The memory limit. The Kubernetes memory task page runs a container past its limit and prints the result: reason: OOMKilled next to exitCode: 137. If the reason says OOMKilled, raise the limit or use less memory.
  • A stop that ran out of patience. docker stop sends SIGTERM by default and, after a grace period, SIGKILL. A process that ignores SIGTERM ends on the second signal, and 128 + 9 is 137. Handle SIGTERM and shut down in time.
  • A timeout with a kill step. GNU timeout sends TERM first and exits 124. Run with -k or -s KILL it sends KILL, and returns 137. Its manual adds that 137 is also what you get when timeout itself is killed, and that the two cases cannot be told apart.

Docker adds three codes of its own. According to the docker run reference, 125 means the error is with the Docker daemon itself, 126 means the contained command cannot be invoked, 127 means it cannot be found, and any other code is the exit code of the command inside the container.

Same number, different meaning

Outside the POSIX rules, a code means whatever its program says it means. These five are worth knowing because wrappers and CI systems act on them.

ToolCodeWhat it means there
grep1No line was selected. An error is 2.
timeout124The command timed out, unless --preserve-status was given.
git bisect run125This commit cannot be tested: skip it. Codes 1 to 127 except 125 mean bad, and anything else aborts the bisect.
docker run125The Docker daemon failed, not your command.
GitHub Actionsany non-zeroThe action's check run is marked failure. Only 0 is success.

Why did my pipeline pass when a command failed?

Because a pipeline has one exit status, and by default it is the last command's. The Bash manual on pipelines says so, and names the switch that changes it: with pipefail on, the pipeline returns the status of the last command that exited non-zero.

bash -c 'false | true; echo $?'
0
bash -c 'set -o pipefail; false | true; echo $?'
1

A CI step such as run-tests | tee log.txt therefore reports the status of tee. Turn pipefail on at the top of the script, or check the test command on its own.

Which exit code should your own CLI return?

The documents above leave most of the range open. This is the advice they add up to, with the reason for each line.

0
Only when the job was done. CI systems read nothing else as success.
1
The general failure. Enough for most tools.
2
Wrong flags or missing arguments, if you want to match the Bash builtins.
3 to 123
Your own named failures, if scripts need to tell them apart. List them in --help or the manual, as grep does.
124, 125
Leave free. timeout, git bisect run and docker run give them meanings, and your tool will run under those wrappers.
126 and up
Leave to the shell. Bash says it "may use values above 125 specially", a caller will read 137 from your tool as a kill, and ssh keeps 255 for its own failures.
Over 255
Never. The value wraps, and 256 arrives as 0.

You may see the BSD list in sysexits.h recommended: 64 for a usage error, up to 78 for a configuration error. The codes are real, but the FreeBSD sysexits(3) page now says the interface "has been deprecated and is retained only for compatibility" and that its use is discouraged. Do not build a new tool around it.

Questions

How do I see the exit code of the last command?

Run echo $? straight after it. The Bash manual calls $? the special parameter that holds the exit status of the last command. Any command in between, even another echo, replaces it.

Is exit code 1 always an error?

No. It is a failure in the shell's sense, so if and && treat it as false, but tools such as grep use 1 for an ordinary "nothing matched". In a script that stops on any failure, that ends the script.

Can a shell report an exit status above 255?

For a signal, POSIX allows it: shells "are permitted to assign an exit status greater than 255 if a command terminates due to a signal". Bash does not. It keeps every status between 0 and 255.

Does exit code 137 always mean out of memory?

No. It means SIGKILL. Out of memory is one common sender. A stop after the grace period and a timeout set to send KILL are two more. Look for the stated reason, such as OOMKilled, before changing a memory limit.

Sources