Skip to content
Latchkey

Exit Code 1 vs Exit Code 2: What the Difference Means

Exit 1 means "something failed", full stop. Exit 2 conventionally means "you used me wrong" - bad arguments or syntax - but many tools bend the rule.

Both 1 and 2 are ordinary non-zero failures, but they hint at different root causes. Knowing the loose convention points your debugging in the right direction faster.

Exit code 1: generic failure

By convention, 1 is the catch-all "the operation failed" code. A test that failed, a build error, an assertion, a non-empty grep no-match - almost any tool reaches for 1 when something went wrong but there is no more specific code to use.

Exit code 2: misuse / usage error

Many programs and the shell itself use 2 for "you invoked me incorrectly" - an unknown flag, a missing required argument, or a syntax error. Bash returns 2 for shell syntax errors; tools like grep use 2 specifically for an *error* (bad file, bad regex) as opposed to 1 for "no match".

Why the rule is loose

There is no enforced standard above 0. Plenty of tools (make, pytest, linters) define their own meanings for 1 and 2, so the convention is a hint, not a guarantee. Always confirm against the specific tool’s documented exit codes.

How to act on it in CI

  • Exit 1 → read the logs; it is a real failure, not a usage issue.
  • Exit 2 → suspect a bad flag, missing arg, or syntax error in the command.
  • When unsure, check that tool’s docs - 1 and 2 are tool-defined above the convention.

Key takeaways

  • Exit 1 is the generic "it failed" code used by almost everything.
  • Exit 2 conventionally means misuse: bad args or syntax errors.
  • The convention is loose - many tools redefine 1 and 2 for themselves.
  • In CI, exit 2 should make you re-read the command, not just the output.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →