Exit code 139: segmentation fault (SIGSEGV, signal 11)
Exit code 139 means the process was killed by SIGSEGV (signal 11), the segmentation fault signal, because 139 = 128 + 11. A segfault means the process tried to access memory it was not allowed to — either reading a null or invalid pointer, writing past an array boundary, or using a dangling pointer. In a scheduled job this is almost always a bug in a C extension, a compiled binary, or a corrupted shared library; the OS kills the process immediately and a retry will not help until the underlying code is fixed.
Why do segfaults appear in scheduled jobs?
A segfault means the process tried to read or write memory at an address it was not permitted to access. The kernel receives a hardware memory-protection fault, sends SIGSEGV to the process, and kills it immediately. The process has no chance to clean up or log a meaningful error — the only evidence is often just the exit code.
In batch jobs the most common sources are:
- C extensions in Python, Ruby, or PHP: a native extension (numpy, Pillow, a database driver compiled in C) has a memory bug that the runtime triggers under certain data patterns or sizes.
- Compiled binaries with bugs: a command-line tool built in C or C++ that dereferences a null pointer on a particular input.
- Corrupted shared libraries: a library update that left mismatched .so files on disk, causing a call through a wrong symbol address.
- Insufficient stack size: a deeply recursive call (or an exceptionally large stack frame) can overflow the stack, which the kernel reports as SIGSEGV.
How do I confirm it was a segfault?
# The kernel logs the segfault — check dmesg and the system journal:
dmesg -T | grep -i "segfault"
journalctl --since "1 hour ago" | grep -i "segfault"
# e.g.: python3[12345]: segfault at 0 ip 00007f... si_code 1
# If core dumps are enabled, gdb can show the stack trace:
ulimit -c unlimited # enable core dump in the current shell (test only)
gdb /usr/bin/python3 core # open the dump; run 'bt' for the backtraceHow do I get a stack trace from a scheduled job?
The most practical approach depends on the language. For Python C extensions, run the job under faulthandler, which prints the Python stack when a signal fires:
# Python: enable faulthandler for a crash-safe stack trace
PYTHONFAULTHANDLER=1 python3 /path/to/job.py
# Or in the script itself:
# import faulthandler; faulthandler.enable()For compiled binaries, build or install a debug version and run under gdb or valgrind to pinpoint the bad memory access. For a recurring segfault in a third-party library, file an upstream issue with the crash address from dmesg and the library version.
How do I get alerted when a job exits 139?
A segfault kills the process immediately, so it will never send a success ping. The monitor alerts on the miss:
PYTHONFAULTHANDLER=1 python3 /path/to/job.py && curl -fsS -m 10 --retry 3 "https://ping.cronshield.com/<your-check-id>"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
- Does a segfault mean my code has a bug?
- Usually yes, somewhere in the call chain — though it may be in a dependency, not your code. A null dereference, an out-of-bounds write, or a use-after-free in a C extension or compiled binary will all produce SIGSEGV. Retry will not fix it; the bug must be identified and patched.
- How is exit 139 different from exit 137?
- Exit 137 = SIGKILL (signal 9), which is sent by an external party (the OOM killer, a container runtime, an operator). Exit 139 = SIGSEGV (signal 11), which is sent by the kernel when the process itself touches memory it should not. 137 is a resource problem; 139 is a code bug.
Primary sources
- GNU Bash Manual — Exit Status (128+N for a process killed by signal N) — verified 2026-07-05
- Linux man-pages: signal(7) — SIGSEGV is signal 11; invalid memory reference — verified 2026-07-05
- Linux man-pages: core(5) — core dump configuration for post-mortem debugging — verified 2026-07-05