핵심 요약
EADDRINUSE는 그 포트를 이미 다른 프로세스가 쓰고 있다는 뜻이다. 점유 중인 PID를 찾아 종료하면 즉시 해결되고, 근본적으로는 서버에 graceful shutdown을 붙여 좀비 프로세스가 남지 않게 한다.
1. 점유 프로세스 찾아 종료
# 포트 3000 점유 프로세스
lsof -i :3000 # 또는: ss -ltnp | grep 3000
kill -9 <PID>
# 한 줄로
kill -9 $(lsof -ti :3000)
2. 재발 방지 — graceful shutdown
const server = app.listen(3000)
process.on('SIGINT', () => server.close(() => process.exit(0)))
process.on('SIGTERM', () => server.close(() => process.exit(0)))
nodemon·tsx watch가 종료 시 포트를 못 놓는 경우가 많은데, close 핸들러가 있으면 깔끔히 반납한다.
3. 함정
- 같은 포트로 두 번 listen하는 코드(중복 실행)일 수도 있다
- Docker에선 컨테이너 포트 매핑 중복 확인
- kill -9는 최후 수단 — 정상 종료(SIGTERM)부터 시도
자주 묻는 질문
껐는데도 포트가 계속 잡혀 있어요.
watch 도구가 자식 프로세스를 남겼거나, 백그라운드에 좀비가 있을 수 있습니다. lsof -ti로 PID를 찾아 종료하고, graceful shutdown을 추가하세요.
TIME_WAIT 상태는 어떻게 하나요?
정상 종료 후 잠깐 남는 상태로 보통 곧 사라집니다. 개발 중 즉시 재바인딩이 필요하면 SO_REUSEADDR(서버 옵션)을 고려하세요.

댓글 0