Claude Code exit code 137: 실행 중 SIGKILL 원인과 해결
Claude Code를 띄워 두고 한 번은 직접 kill -9로, 한 번은 메모리 상한을 건 cgroup 안에서 OOM 킬러가 끝내게 해 봤습니다. 둘 다 종료 코드는 137이었어요. 사람이 끝냈든 커널이 끝냈든 숫자는 똑같더라고요.
그래서 세션이 Claude Code process exited with code 137 한 줄만 남기고 끊겼을 때, 숫자만 봐서는 누가 끝냈는지 알 수 없습니다. 137은 Claude Code 프로세스가 SIGKILL(9번 신호)을 받고 끝났다는 뜻일 뿐이에요(137 = 128 + 9).
Linux라면 dmesg | grep 'Killed process'부터 보세요. (claude)가 찍혀 있으면 메모리 부족이나 컨테이너 메모리 상한이고, 없으면 Claude Code를 띄운 앱이나 스크립트 쪽입니다.
2026년 10월 3일 Ubuntu 24.04 · Claude Code 2.1.287 · Node.js 22.22.0 테스트 환경에서 직접 재현했고, 10월 13일에는 Windows 11 · Claude Code 2.1.296 · Node.js 24.14.0에서도 강제로 끝내 봤습니다. macOS와 데스크톱 앱 사례는 공개 이슈를 인용했습니다.
설치 도중 Installation was killed before it could finish (exit code 137)가 났다면 설치·로그인 오류 글의 메모리 부족 절을 보세요.
확인한 버전·환경
- Claude Code 2.1.296 · Windows 11 · Windows PowerShell 5.1 · 확인일 2026-10-13
- Node.js 24.14.0 · Windows 11 · Windows PowerShell 5.1 · 확인일 2026-10-13
- Claude Code 2.1.287 · Ubuntu 24.04 · bash 5.2 · 확인일 2026-10-03
- Node.js 22.22.0 · Ubuntu 24.04 · bash 5.2 · 확인일 2026-10-03
137은 보낸 쪽을 말해 주지 않는다
셸은 신호로 끝난 프로세스의 종료 코드를 128 + 신호 번호로 돌려줍니다. 낯선 종료 코드가 128보다 크면 kill -l로 신호 이름부터 확인하세요.
$ kill -l 137
KILL
$ kill -l 143
TERM
SIGTERM(143)은 프로세스가 받아서 정리할 수 있지만, SIGKILL은 가로챌 수 없습니다. 그래서 Claude Code는 마지막 메시지를 남길 틈이 없고 화면에는 종료 코드만 남아요. 이 메시지는 IDE 확장이나 Agent SDK 앱처럼 Claude Code를 띄운 프로그램이 내는 오류이고, 종료 코드만으로는 무엇이 실패했는지 알 수 없습니다. 원인은 Claude Code 안이 아니라 바깥에서 찾아야 합니다.
137이면 메모리 부족이라고 단정하기 쉬운데, 늘 그렇지는 않습니다. Linux에서 메모리가 적은 호스트라면 대개 커널의 OOM 킬러지만, 사람이나 스크립트가 보낸 kill -9도 똑같이 137이에요. 설치 스크립트도 macOS에서 난 137에는 메모리 부족 설명을 붙이지 않습니다.
kill -9도 OOM 킬러도 137이었다
로그인 없이도 계속 떠 있는 claude mcp serve(Claude Code를 MCP 서버로 띄우는 명령)를 실행해 두고 두 가지로 끝내 봤습니다. 하나는 직접 kill -9, 하나는 메모리 상한을 건 cgroup 안에서 띄워 OOM 킬러가 끝내게 하는 것입니다.
| 끝낸 방식 | 종료 코드 | oom_kill 횟수 |
커널 로그 |
|---|---|---|---|
직접 kill -9 |
137 | 해당 없음 | 없음 |
| 상한 100MB | 6초 뒤에도 살아 있어 직접 SIGTERM → 143 | 0 → 0 | 없음 |
| 상한 50MB | 137 | 0 → 1 | Killed process … (claude) |
| 상한 30MB | 137 | 1 → 2 | Killed process … (claude) |
종료 코드는 같고 커널 로그만 다릅니다. 137을 가르는 단서는 종료 코드가 아니라 이 한 줄이었어요. 50MB·30MB에서 남은 줄은 이렇게 시작했습니다.
$ dmesg | grep 'Killed process'
Memory cgroup out of memory: Killed process 2234 (claude) total-vm:5590160kB, anon-rss:49472kB, file-rss:87948kB, …
cgroup(컨테이너·서비스 단위) 상한에 걸리면 줄 앞머리가 Memory cgroup out of memory였습니다.
상한보다 큰 RSS로도 죽지 않았다
상한 100MB인데 ps가 보여 준 RSS는 159,108KB(약 155MB)였고, 6초 넘게 살아 있었습니다.
50MB에서 죽을 때 로그를 보면 anon-rss가 49,472KB, file-rss가 87,948KB로 파일에서 읽은 쪽이 더 컸어요. cgroup은 상한을 넘으면 먼저 메모리 회수를 시도하므로, 다시 읽을 수 있는 파일 쪽을 내주며 버틴 것으로 추정합니다.
판단은 RSS 추정이 아니라 oom_kill 횟수와 커널 로그로 하는 편이 정확했습니다.
직접 띄우면 137이라는 숫자 자체가 없었다
Node.js에서 Claude Code를 띄우고 그 프로세스만 SIGKILL로 끝냈습니다. 두 번 돌려 같은 결과였어요.
| 띄운 방식 | Node.js가 받은 값 |
|---|---|
spawn('claude', …) 직접 |
code=null, signal=SIGKILL |
sh -c 'claude …'로 감싸서 |
code=137, signal=null |
셸이 신호를 128 + 번호로 바꿔 넘기기 때문입니다. TypeScript Agent SDK도 신호로 끝난 프로세스는 Claude Code process terminated by signal <name> 형태로 알립니다. 그러니 exited with code 137이 떴다면 그 사이 어딘가에 신호를 숫자로 바꾼 층이 있었을 가능성이 큽니다.
Claude Code를 띄우는 스크립트를 만든다면 종료 코드와 신호를 둘 다 기록해 두세요.
Windows에서는 137 대신 1이 남았다
Windows에는 신호가 없습니다. 같은 Node.js 코드로 Windows 11에서 Claude Code를 띄우고 두 가지 방법으로 강제로 끝내 봤어요.
| 끝낸 방식 | Node.js가 받은 값 |
|---|---|
띄운 쪽에서 kill('SIGKILL') |
code=null, signal=SIGKILL |
바깥에서 taskkill /F /PID <pid> |
code=1, signal=null |
Node.js는 자기가 보낸 종료에는 신호 이름을 붙여 주지만, taskkill /F로 끝내면 종료 코드 1이 남았습니다. 그래서 Windows에서는 137이라는 숫자가 나오지 않을 수 있어요.
Windows에서 세션이 다른 오류 문구 없이 exited with code 1로 끊겼다면, 작업 관리자나 정리 스크립트가 강제로 끝낸 경우도 같이 의심해 보세요.
누가 보냈는지 가리는 순서
1. 커널 로그에 Killed process <pid> (claude)가 있는지
Linux에서 dmesg | grep 'Killed process'를 실행합니다. 있으면 OOM 킬러이고, Memory cgroup으로 시작하면 컨테이너·서비스의 상한을, 아니면 기기 전체 메모리를 보세요. 컨테이너 안이라면 그 cgroup의 횟수로도 확인할 수 있습니다.
grep oom_kill /sys/fs/cgroup/memory.events # cgroup v2
grep oom_kill /sys/fs/cgroup/memory/memory.oom_control # cgroup v1
oom_kill이 늘었다면 그 cgroup 안에서 OOM 킬러가 프로세스를 끝낸 것입니다. 테스트 환경은 v1이었고, v2의 memory.max(상한)와 memory.events의 oom_kill은 커널 문서를 기준으로 적었습니다.
2. 커널 로그가 비었으면 띄운 프로그램의 로그
데스크톱 앱·IDE 확장·Agent SDK 앱이 직접 끝냈을 수 있습니다. VS Code에서는 오류와 함께 보이는 View output logs 링크로 실제 실패를 확인하세요. 아래 공개 사례 중 한 건은 데스크톱 앱 자신의 로그에서 강제 종료 기록을 찾았습니다.
3. 그래도 없으면 스크립트나 사람의 kill -9
CI의 시간 제한, 오래 걸리는 프로세스를 정리하는 스크립트가 여기에 해당합니다. 직접 보낸 kill -9는 커널 로그에 아무것도 남기지 않았어요.
같은 프로젝트에서 터미널로 claude를 직접 실행해 보는 것도 방법입니다. 실패가 대개 실제 오류 메시지와 함께 재현되지만, 메모리 부족처럼 상황이 겹쳐야 나는 137은 바로 재현되지 않을 수 있습니다.
메모리가 원인이라면
큰 코드베이스를 다루면 Claude Code 자체가 자원을 많이 쓸 수 있습니다. 이 순서로 손보세요.
/compact로 컨텍스트를 줄이고, 큰 작업 사이에는 Claude Code를 닫았다가 다시 엽니다. 압축과 초기화를 고르는 기준은 컨텍스트가 찼을 때/compact·/clear·서브에이전트 고르기에 있습니다.- 세션 힙 메모리가 2.5GB를 넘으면 경고가 뜹니다. Claude Code를 다시 시작하고
claude --continue로 대화를 새 프로세스에서 이어 갑니다. - 그래도 높으면
/heapdump로 진단 파일 두 개를 만듭니다.
주의:
/heapdump가 만드는.heapsnapshot에는 대화 전체와 자격 증명까지 들어 있습니다. 공개 이슈에는-diagnostics.json파일만 붙이세요.
메모리를 늘리면 끝날 것 같지만, 죽는 쪽이 꼭 범인은 아닙니다. cgroup은 상한을 넘으면 회수를 시도하고, 실패하면 cgroup 안에서 가장 큰 프로세스를 골라 끝내거든요. 함께 돌던 빌드나 테스트 때문에 상한에 닿았어도 죽는 쪽은 Claude Code일 수 있으니, 같이 도는 프로세스부터 보세요.
상한 자체가 작은 것도 흔한 원인입니다. 설치 요구사항은 RAM 4GB 이상이고, 이보다 작은 컨테이너에서 Claude Code와 빌드를 함께 돌리면 OOM 킬러가 끼어들 여지가 커집니다.
비슷한 메시지들
비슷해 보여도 누가 끝냈느냐에 따라 갈립니다.
Claude Code process exited with code 137
VS Code 확장, Agent SDK 앱, 데스크톱 앱이 이 문구를 보여 주고 세션이 끊깁니다. SIGKILL로 끝났다는 것만 알려 주니, 위 순서대로 커널 로그 → 띄운 프로그램의 로그 → 호출부를 봅니다.
Claude Code process terminated by signal SIGKILL
TypeScript Agent SDK 앱에서 나는 형태입니다. 신호로 끝난 프로세스는 종료 코드 대신 이렇게 보고되니, 137과 같은 사건으로 보고 똑같이 가리면 됩니다. SDK에 stderr 콜백을 넘겨 CLI 출력을 받아 두되, SIGKILL은 마지막 출력을 쓸 기회를 주지 않으니 앱 쪽에서 종료 시각과 그때의 메모리 사용량도 함께 기록해 두세요.
FATAL ERROR: … JavaScript heap out of memory
메모리 문제인데 137이 아니라 134로 끝납니다. 커널이 아니라 Node.js 런타임이 스스로 멈춘 경우예요. 힙 한도를 64MB로 낮춘 Node.js 스크립트로 직접 재현했습니다.
$ node --max-old-space-size=64 -e 'const a=[]; for(;;) a.push({x: new Array(1000).fill(1)})'
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
$ echo $?
134
134는 128 + 6(SIGABRT)입니다. FATAL ERROR: 뒤 앞부분은 실행마다 달랐으니 JavaScript heap out of memory로 검색하세요.
Claude Code가 이 메시지로 끝났다면 위의 /heapdump부터 해 보세요. 요약이 메모리가 JS 힙에 몰렸다고 하면 .heapsnapshot을 Chrome DevTools의 Memory 탭에서 엽니다.
Installation was killed before it could finish (exit code 137)
실행 중이 아니라 설치 단계의 137입니다. Linux의 메모리가 적은 호스트에서 대개 OOM 킬러가 claude install을 끝낸 것이니, 메모리를 비우거나 스왑을 더해 다시 설치합니다. 절차는 설치·로그인 오류 글에 있습니다.
다른 사람들이 겪은 문제
GitHub 공개 이슈의 보고입니다. 세 건 모두 macOS의 Claude 데스크톱 앱(Cowork 포함)에서 난 137입니다.
- kuldiph(2026-04-22, 이슈 #51796, 데스크톱 앱 1.3883.0): Cowork에서 간단한 요청도 매번 137로 끝났고, 128GB 기기를 재시작해 Claude만 띄워도 같았다고 보고했습니다. 원인이나 우회법은 적지 않았고 “not planned”로 닫혔습니다.
- klb-solutions(2026-08-27, 이슈 #90109, 데스크톱 앱 1.37937.3, Claude Code 2.1.246, macOS 26.6.1, 16GB): 앱이 작업 프로세스를 죽이면서 화면에는
Blocked by endpoint security를 띄웠고, 앱 로그에Claude Code process terminated by signal SIGKILL이 남았다고 보고했습니다. 보고자는 종료가 앱 로그의sys_free_raw가 약 800MB 아래일 때만 났다고 분석했지만, 그 값이 800MB 아래였던 측정 177번은 종료로 이어지지 않아 조건일 뿐 방아쇠는 아니라고 스스로 적었습니다. 다른 앱을 닫아 여유 메모리를 높게 유지하는 것이 보고자의 우회법이었습니다. - samgob(2026-08-31, 이슈 #90889, 번들 Claude Code 2.1.229·2.1.247, 36GB): 예약 작업 등으로 띄운 헤드리스 실행이 끝난 뒤에도 프로세스가 남아 사흘 동안 78개가 7.72GB를 차지했고, 스왑이 95% 찬 상태에서 대화형 세션이 137로 죽었다고 보고했습니다. 앱을 재시작하자 78개가 2개로 줄었고, 남은 프로세스를 정리하는 스크립트와 주 1회 재시작을 우회책으로 쓴다고 적었습니다.
원인을 짚은 두 건은 모두 Claude Code 바깥(앱 로그, 프로세스 목록)에서 단서를 찾았습니다. macOS에서는 dmesg 확인을 그대로 옮겨 쓸 수 없으니, 위 순서의 2번인 앱 로그와 ps로 본 claude 프로세스 수부터 보는 편이 맞습니다. 직접 실행한 claude -p가 끝나지 않는 경우는 -p 비대화형 모드 글에 따로 정리했습니다.
마치며
직접 끝내 보면 분명해집니다. 137은 끝난 방식일 뿐이고, SIGKILL을 보낸 쪽은 Claude Code 바깥에 있어요. Linux에서는 커널 로그의 Killed process … (claude) 한 줄과 oom_kill 횟수가 가르고, macOS·데스크톱 앱에서는 앱 로그와 남아 있는 claude 프로세스 수가 먼저입니다.
다음에 137이 뜨면 다른 걸 건드리기 전에 dmesg | grep 'Killed process'부터 실행해 결과를 남겨 두세요. 긴 세션이 메모리를 붙잡는 문제라면 컨텍스트가 찼을 때 /compact·/clear·서브에이전트 고르기로 이어집니다.
참고한 공식 자료
- Error reference —
Claude Code process exited with code N이 띄운 프로그램의 오류라는 분류, 종료 코드만으로는 원인을 알 수 없다는 점, Linux에서 137이 대개 OOM 킬러라는 설명 (2026-10-03 확인) - Agent SDK troubleshooting — 신호로 끝난 프로세스를
terminated by signal <name>으로 보고,stderr콜백 (2026-10-03 확인) - Troubleshooting — High CPU or memory usage —
/compact, 2.5GB 경고와claude --continue,/heapdump와 진단 파일 취급 (2026-10-03 확인) - Set up Claude Code — 하드웨어 요구사항 RAM 4GB 이상 (2026-10-03 확인)
- Linux 커널 문서 — Control Group v2 —
memory.max와memory.events의oom_kill(2026-10-03 확인) - Linux 커널 문서 — cgroup v1 Memory Resource Controller — 상한 초과 시 회수 뒤 가장 큰 작업을 끝내는 순서 (2026-10-03 확인)
인용한 공개 사례
- kuldiph, 2026-04-22, anthropics/claude-code#51796 — Claude Cowork Tasks Always Ends in = Claude Code process exited with code 137
- klb-solutions, 2026-08-27, anthropics/claude-code#90109 — Desktop app SIGKILLs its own Claude Code workers on a healthy Mac, then blames endpoint security
- samgob, 2026-08-31, anthropics/claude-code#90889 — Headless (desktop-app agent-mode) runs complete their work but the claude process never exits
변경 이력
- 2026-10-14 — taskkill /F 한 번의 결과를 다른 프로그램이 끝낸 경우 전체로 일반화한 문장을 고쳤습니다.
- 2026-10-13 — Windows 11에서 Node.js로 띄운 Claude Code를 강제로 끝내 본 결과를 더했습니다. 띄운 쪽의 kill('SIGKILL')은 signal=SIGKILL로, 바깥의 taskkill /F는 종료 코드 1로 남아 Windows에서는 137이 나오지 않을 수 있습니다.