Skip to content
Get started

Exit code 130: interrupted by SIGINT (signal 2)

Exit code 130 means the process received SIGINT (signal 2), because 130 = 128 + 2. In an interactive terminal this is what Ctrl+C sends. In a scheduled job, SIGINT usually comes from a supervisor, a watchdog, or a script that sent it explicitly — it is unusual from the OS in a batch context, but it does appear when a job scheduler or CI system interrupts a step.

What sends SIGINT to a scheduled job?

  • A CI runner cancelling a step: GitHub Actions, GitLab CI, and similar systems send SIGINT to the process group when a job is cancelled or times out — before escalating to SIGTERM and then SIGKILL.
  • A supervisor or process manager: a script or orchestrator that explicitly runs kill -2 <pid> to interrupt a child process.
  • A timeout wrapper that chooses SIGINT: some job frameworks send SIGINT (rather than SIGTERM) as the initial stop signal, following the same convention as a terminal.
  • An interactive session accident: a developer running a cron command manually in a terminal and pressing Ctrl+C — though this leaves exit 130 in a run log that later looks like a scheduler event.

How is exit 130 different from exit 143 (SIGTERM) and exit 137 (SIGKILL)?

All three are signal-termination codes (128 + N). The signal number tells you the reason: SIGINT (130, signal 2) is an interruption request — the same thing a Ctrl+C produces. SIGTERM (143, signal 15) is a graceful stop request that the process can catch and handle. SIGKILL (137, signal 9) is an uncatchable, immediate kill — the process gets no chance to clean up.

In practice: exit 130 in a batch context means something sent an explicit interrupt, not an OOM kill or a graceful shutdown. Check what was running at the time the job was killed.

How do I trap SIGINT for graceful cleanup?

Because SIGINT is catchable, a long-running batch job can trap it to clean up partial state before exiting:

#!/usr/bin/env bash
cleanup() {
  echo "Interrupted — saving checkpoint before exit"
  save_checkpoint
  exit 130   # preserve the conventional exit code
}
trap cleanup INT

process_batches   # long-running work

How do I get alerted when a job exits 130?

Ping only on a clean exit so an interrupted job withholds the ping and alerts:

run_the_job && curl -fsS -m 10 --retry 3 "https://ping.cronshield.com/<your-check-id>"
On paid tiers, CronShield reads the run output and helps identify whether SIGINT came from a CI cancellation, a timeout policy, or an explicit interrupt. PING_URL is a placeholder for the endpoint you get on a monitor.

Catch this failure automatically

The free tier gives you a heartbeat endpoint and an email alert when an expected ping doesn't arrive. Paid tiers add the log-aware diagnosis — the last log line and a likely cause in the alert. The heartbeat receiver ships in an upcoming release; see the plans to learn what each tier adds.

Frequently asked questions

Is SIGINT the same as Ctrl+C?
Yes. Ctrl+C in a terminal sends SIGINT (signal 2) to the foreground process group, causing exit 130. In a scheduled job, SIGINT doesn't come from a keyboard — it comes from a CI runner, a supervisor, or an explicit kill -2 call.
What is the difference between exit 130 (SIGINT) and exit 143 (SIGTERM)?
Both are catchable interrupt signals, but they carry different semantics. SIGINT (130) is an interruption request — it conventionally means the user or a supervisor wants to stop the process now. SIGTERM (143) is a graceful shutdown request — orchestrators send it first when tearing down a container or service, and processes are expected to finish in-flight work and clean up.