Skip to content
Latchkey

Exit Codes and Signals in CI/CD: A Practical Guide

Every CI step ends with an exit code. Knowing the common ones turns a cryptic failure into an obvious next step.

A CI job fails when a step returns a non-zero exit code. Most codes fall into a few well-understood buckets: ordinary failures, "command not found", timeouts, and signal-based terminations. Here is what the ones you actually see mean.

Ordinary failures (1, 2)

Exit 1 is the generic "something failed" - almost any tool uses it. Exit 2 often means misuse of a shell builtin, but many tools (make, grep, pytest) also use 2 for their own errors. Neither tells you much on its own; read the logs.

"Command not found" and not executable (127, 126)

Exit 127 means the shell could not find the command - usually a missing tool or a PATH problem. Exit 126 means the file was found but is not executable (wrong permissions or a broken interpreter line).

Timeouts (124)

GNU timeout returns 124 when a command exceeds its time limit. In CI this is frequently a transient hang or a slow network call, though it can also be a genuine deadlock.

Signals (128 + N): 130, 137, 143

A process killed by signal N exits with 128 + N. The common ones: 130 = SIGINT (Ctrl-C / cancellation), 137 = SIGKILL (usually OOM), 143 = SIGTERM (graceful stop, cancellation, or spot-instance preemption).

Key takeaways

  • Codes above 128 mean the process was killed by a signal (code − 128 = signal).
  • 127 = command not found; 126 = found but not executable.
  • 124 = timed out; often transient in CI.
  • 137 = SIGKILL (usually OOM); 143 = SIGTERM; 130 = SIGINT.

Related guides

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