Node.js EADDRINUSE: 이미 사용 중인 포트 찾고 안전하게 종료하기

Node.js 개발 서버가 EADDRINUSE로 시작되지 않을 때 포트 점유 프로세스를 확인하고 정상 종료한 뒤 재발을 막는 방법을 정리합니다.

JavaScript / Node.jsWindows · macOS · Linux

짧은 요약

EADDRINUSE는 코드 문법 오류가 아니라 다른 프로세스가 같은 주소와 포트를 이미 듣고 있다는 뜻입니다. 포트를 점유한 PID를 확인해 정상 종료하거나 애플리케이션 포트를 바꾸세요.

증상과 환경

Node.js, Express, Vite 또는 Next.js 개발 서버를 시작할 때 listen EADDRINUSE: address already in use :::3000 같은 메시지가 표시됩니다. 서버를 강제 종료한 직후나 터미널을 여러 개 열었을 때 자주 발생합니다.

원인

이전 개발 서버가 백그라운드에 남았거나 다른 애플리케이션이 동일한 포트를 사용하고 있습니다. 자동 재시작 도구가 종료된 프로세스를 다시 띄우는 경우도 있습니다.

재현 예시

import http from 'node:http';
http.createServer((req, res) => res.end('first')).listen(3000);
http.createServer((req, res) => res.end('second')).listen(3000);

두 서버가 같은 프로세스에서 3000번 포트를 열려고 하므로 두 번째 listen에서 오류가 납니다.

단계별 해결법

1. 포트 점유 프로세스 확인

Windows에서는 다음 명령으로 PID를 확인합니다.

Get-NetTCPConnection -LocalPort 3000 -State Listen | Select-Object LocalAddress,LocalPort,OwningProcess
Get-Process -Id <PID>

macOS와 Linux에서는 다음처럼 확인합니다.

lsof -nP -iTCP:3000 -sTCP:LISTEN

2. 프로세스를 정상 종료

프로세스가 실행 중인 터미널을 찾을 수 있다면 Ctrl+C로 종료하는 것이 우선입니다. 찾을 수 없을 때만 PID를 지정합니다.

Stop-Process -Id <PID>
kill <PID>

곧바로 강제 종료 옵션을 쓰면 정리 작업이나 로그 기록이 누락될 수 있습니다.

3. 포트를 변경해야 하는 경우

const port = Number(process.env.PORT || 3001);
server.listen(port);

팀 프로젝트라면 .env.example과 실행 문서에도 포트를 함께 기록하세요.

확인법

점유 확인 명령을 다시 실행해 기존 PID가 사라졌는지 확인하고 서버를 한 번만 시작합니다. 브라우저에서 해당 포트로 접속한 뒤 로그에 서버 시작 메시지가 한 번만 찍히는지도 봅니다.

주의사항

이름이 비슷하다는 이유로 모든 Node.js 프로세스를 한꺼번에 종료하지 마세요. 다른 프로젝트나 편집기 확장 기능까지 중단될 수 있습니다.

관련 이슈

  • Docker 포트 매핑 충돌
  • 테스트 종료 후 열린 서버 핸들
  • nodemon과 프로세스 관리자 중복 실행