Exit Code 137の解説: CIにおけるSIGKILLとOOM Killer
exit code 137は、プロセスがSIGKILLによって終了させられたことを意味します。この数字は128 + 9で、9はsignalです - そしてCIでは犯人はほぼ常にout-of-memory killerです。
CIのstepがexit code 137で終わったとき、それはそのコードを「返した」のではなく - killされたのです。そのエンコーディングを理解すれば、何が起きたか、そしてなぜ通常stack traceがないのかが正確に分かります。
128 + Nのエンコーディング
Unixの慣習により、signal Nによって終了させられたプロセスはexit code 128 + Nを報告します。SIGKILLはsignal 9なので、128 + 9 = 137です。同様にSIGTERM(15)は143、SIGINT(2)は130です。128を超えるコードを見たら、それはプログラム自身のロジックではなく、signalがプロセスを終わらせた合図です。
CIでほぼ常にOOMである理由
SIGKILLはキャッチ、ブロック、無視ができないため、カーネルはプロセスを即座に強制終了させなければならないときにこれを使います。メモリが限られたCI runnerでは、最も一般的な原因は、cgroupのout-of-memory killerが最も重いプロセスをkillしてメモリを回収することです。だからこそ137は、通常Killedという言葉だけでtracebackなしに現れます。
確認と修正の方法
- 失敗の前後でrunnerのメモリ使用量を確認するか、カーネルログの
oom-kill行を確認します。 - jobにより多くのメモリを与えるか、ピーク使用量を減らします(並列度を下げる、言語のheapに上限を設ける)。
- メモリに問題がなさそうなら、外部のwatchdogや
timeout --signal=KILLを除外します。
重要なポイント
- Exit code 137 = SIGKILLによるkill(128 + 9)。
- CIでは圧倒的にout-of-memory killerです。
- SIGKILLはトラップできないため、stack traceがめったにありません。
- 修正は機械的です。メモリを増やすか、ピーク使用量を下げます。
よくある質問
exit 137はメモリ不足なしに起こりえますか?
はい - 外部のwatchdogや
kill -9を含め、あらゆるSIGKILLが137を生じます。しかしメモリが制約されたCI runnerでは、OOMが圧倒的に最も可能性の高い原因です。関連ガイド
Exit Codes and Signals in CI/CD: A Practical GuideA practical guide to process exit codes and signals in CI/CD - what 1, 2, 124, 126, 127, 130, 137, and 143 me…
Docker Build Exit Code 137 (OOM Killed) - Fix Out-of-Memory BuildsDocker build or container exiting with code 137 means the process was OOM-killed. Learn why it happens in CI…
Self-Healing CI: Recovering from OOM-Killed Jobs (Exit 137)Out-of-memory kills (exit 137) are mechanical, not code bugs. See the manual fix and how self-healing CI auto…
Node.js "JavaScript heap out of memory" in CI - Fix FATAL Heap ErrorsFix "FATAL ERROR: Reached heap limit - JavaScript heap out of memory" in CI builds by raising the V8 heap lim…