BlueByte
EADDRINUSEFixed

EADDRINUSE: address already in use — 포트 비우기

작성 Haneul Seo2026년 8월 15일 업데이트5 min

안녕하세요, BlueByte입니다. EADDRINUSE는 앱이 쓰려는 포트를 이미 무언가 쥐고 있다는 뜻일 뿐입니다 — 대개 종료되지 않은 앱 자신의 이전 실행이죠. 오늘은 무엇이 쥐고 있는지 정확히 찾고, 멈출지 앱을 옮길지 정하고, 포트가 비어 보이는데도 안 바인드되는 경우까지 짚는 순서로 가보겠습니다.

이 오류가 뜻하는 것

서버 시작이 실패합니다:

Error: listen EADDRINUSE: address already in use :::3000

포트가 점유됐습니다. 다른 프로세스 — 대개 종료되지 않은 같은 앱의 이전 실행 — 가 이미 쥐고 있어 새 프로세스가 바인드하지 못합니다. 해결은 쥔 쪽이 죽일 수 있는 남은 인스턴스인지 실제로 필요한 서비스인지에 달렸으니, 첫 일은 그것을 식별하는 것입니다.

포트가 이미 점유된 이유

인터페이스당 특정 TCP 포트는 한 프로세스만 리스닝합니다. EADDRINUSE가 나는 때:

  • 이전 인스턴스가 아직 실행 중 — 가장 흔한 경우, 특히 크래시나 서버를 멈추지 않고 닫은 터미널 후.
  • 다른 서비스가 정당하게 같은 포트를 씀.
  • 크래시한 프로세스가 소켓을 연 채 — 풀릴 때까지 포트가 쥐여 있음.
  • 빠른 재시작에서 이전 소켓이 TIME_WAIT이라 포트가 아직 재바인드 불가.

무엇이 쥐고 있는지 정확히 찾기

눈감고 죽이지 말고 쥔 것을 먼저 찾으세요. Linux:

ss -ltnp | grep :3000

macOS:

lsof -nP -iTCP:3000 -sTCP:LISTEN

둘 다 PID와 프로그램명을 출력합니다. 이름이 이전 실행의 내 앱이면 남은 인스턴스, 의존하는 다른 것이면 죽이지 말고 앱을 옮기세요. LISTEN으로 아무것도 안 뜨는데 빠른 재시작에서 바인드 못 하면 포트가 TIME_WAIT — ss -tan | grep :3000이 보여줍니다.

쥔 것을 멈추거나, 앱을 옮기기

  1. 남은 인스턴스면 멈춥니다:
kill 12345          # 정상
kill -9 12345       # 무시하면
  1. 쥔 게 필요한 서비스면 앱을 다른 포트로:
PORT=3001 npm start

실제 사례: 분리된 개발 서버

Ctrl+C로 개발 서버를 멈추고 파일을 고친 뒤 재시작하는데 EADDRINUSE :::3000으로 실패합니다. ss -ltnp | grep :3000이 이전 실행의 node 프로세스가 아직 리스닝 중임을 보여줍니다 — 앞서 터미널을 닫은 게 멈춘 게 아니라 분리한 것입니다. 그 PID를 kill하고 ss에 더는 안 뜨는 것을 확인한 뒤 서버를 시작하니 깨끗이 바인드합니다. 빠른 재시작에서 계속 이러니, 개발 서버가 주소를 재사용하게 바꿔 남은 TIME_WAIT 소켓이 재바인드를 막지 않게 합니다.

포트가 내 것인지 확인

서버를 다시 시작해 바인드를 확인:

ss -ltnp | grep :3000   # 이제 새 프로세스만 표시

깨끗이 시작하고 리스너가 내 앱이면 포트는 내 것입니다.

다시 겪지 않으려면

서버를 깨끗이 종료하고(창을 닫지 말고 Ctrl+C), systemd·pm2·Docker 같은 감독자가 옛 프로세스를 계속 되살리면 PID를 손으로 죽이지 말고 거기서 멈추세요. 빠른 개발 재시작엔 주소 재사용을 켜 소켓이 남지 않게 하세요.

ECONNREFUSED·EACCES와의 구분

EADDRINUSE는 로컬 충돌 — 내 기기의 포트가 점유됨. ECONNREFUSED는 반대편 — 연결하려는데 리스너가 없음. 1024 미만 낮은 포트의 EACCES는 충돌이 아니라 권한 문제 — 그 포트엔 상승 권한이 필요합니다. EADDRINUSE를 만나면 무언가 죽이기 전에 ss/lsof로 쥔 것을 식별하세요.

관련 질문

kill로 포트가 안 풀렸습니다. 이제 어떻게 하죠?

프로세스가 신호를 무시했거나 다시 떴습니다. ss/lsof로 PID를 재확인하고 최후에 kill -9를 쓰세요. 다시 뜨면 감독자(systemd, pm2, docker)가 재시작하는 것이니 거기서 멈추세요.

포트는 비었는데 재시작에서 계속 EADDRINUSE가 납니다.

이전 소켓이 TIME_WAIT 상태입니다. 잠시 기다리거나, 서버를 주소 재사용(SO_REUSEADDR)을 켠 채 실행해 바로 재바인드하게 하세요.

:::3000엔 왜 콜론이 셋인가요?

포트 3000의 IPv6 와일드카드 주소입니다. 서버가 모든 IPv6 인터페이스에서 리스닝 중이며, 포트 충돌은 IPv4/IPv6와 무관하게 같습니다.

1024 미만 포트에서만 EADDRINUSE가 납니다.

그건 충돌이 아니라 EACCES(권한)일 수 있습니다 — 1024 미만 포트는 상승 권한이 필요합니다. 더 높은 포트를 쓰거나 권한을 부여하세요.

Docker 컨테이너가 포트가 사용 중이라고 합니다.

이전 컨테이너가 아직 게시 중일 수 있습니다. docker ps -a --filter publish=3000으로 옛 컨테이너를 제거하거나 게시 호스트 포트를 바꾸세요.

참고 자료

Haneul Seo

Infrastructure engineer · 10+ years running Linux fleets

같은 카테고리 다른 글

Start request repeated too quicklyFixed

systemd: Start request repeated too quickly

systemd는 StartLimitIntervalSec(기본 10초) 안에 StartLimitBurst(기본 5회)보다 많이 시작된 유닛의 시작을 거부하며, Restart=도 이 제한에 포함됩니다. 기본 RestartSec 100ms로는 크래시하는 서비스가 1초도 안 되어 다섯 번을 소진합니다. 저널에서 진짜 크래시를 찾아 고치고, reset-failed를 실행한 뒤, RestartSec로 재시작에 여유를 주세요.

systemd
Too many authentication failuresFixed

SSH: Received disconnect ... Too many authentication failures

agent가 서버가 허용하는 것보다 많은 키를 내밀고 있습니다. sshd가 들여다보는 공개키 하나하나가 MaxAuthTries 시도를 한 번씩 소모하고 — 기본 6회, 하드닝된 호스트에서는 3회인 경우가 많습니다 — 정작 맞는 키는 차례가 오기 전에 연결이 끊깁니다. IdentitiesOnly=yes와 명시적 IdentityFile로 키 하나를 고정하면 시도 횟수가 1로 떨어집니다.

OpenSSH
1722Fixed

Active Directory: 복제가 error 1722(The RPC server is unavailable)로 실패

RPC는 하위 계층이 연결에 실패했을 때 1722(0x6ba, RPC_S_SERVER_UNAVAILABLE)를 보고합니다. 따라서 진짜 원인은 RPC 자신이 아니라 DNS, 차단된 포트, 두 도메인 컨트롤러 중 한쪽의 호스트 설정입니다. repadmin이 어느 파트너가 실패하는지 알려주고, dcdiag /test:dns가 이름 해석을 배제하며, Test-NetConnection과 동적 포트 범위가 방화벽 문제를 가릅니다. 가장 흔한 실수는 TCP 135만 허용하고 49152–65535는 막아 둔 규칙입니다.

Windows Server Active Directory
Windows Server RDSFixed

Windows Server RDS: The remote session was disconnected because there are no Remote Desktop License Servers available to provide a license

120일 RD Licensing 유예 기간이 끝났는데 세션 호스트가 쓸 수 있는 라이선스 서버가 없어 세션을 거부하는 상황입니다. GetGracePeriodDays 의 DaysLeft 가 0 이고 SpecifiedLSList 가 비어 있으면 몇 초 만에 확인됩니다. 해결은 활성화된 라이선스 서버와, 호스트 버전을 감당할 만큼 새 CAL 입니다. 2019 CAL 은 2022 세션 호스트를 서비스하지 못합니다. 여기에 배포 또는 Licensing 정책 설정과 두 서버 사이의 RPC 포트 개방이 따라옵니다.

Windows Server RDS
0x80070035 / Event ID 31017Workaround

Windows 11: NAS 공유 폴더를 열 때 "조직의 보안 정책이 인증되지 않은 게스트 액세스를 차단" (0x80070035)

Windows 10 Enterprise/Education/Pro for Workstations, Windows 11 Pro, Windows Server 2019 이후의 SMB 클라이언트는 기본적으로 게스트 로그온을 거부하고, Windows 11 24H2 Enterprise/Pro/Education 은 게스트 세션이 할 수 없는 SMB 서명까지 요구합니다. 그래서 게스트 접근만 제공하는 NAS 공유는 'block unauthenticated guest access' 대화상자, Error code 0x80070035, 또는 System error 3227320323 으로 실패하고, SmbClient/Security 로그에 Event ID 31017 'Rejected an insecure guest logon' 이 남습니다. Microsoft 가 권하는 해결은 NAS 에 실제 계정을 만들고 펌웨어에서 서명을 지원하게 하는 것입니다. Set-SmbClientConfiguration -EnableInsecureGuestLogons $true(24H2 는 -RequireSecuritySignature $false 까지)는 비상구이며, 그 클라이언트의 서명과 암호화를 포기하는 대가가 있습니다.

Windows (SMB client)
E: Could not get lock /var/lib/dpkg/lock-frontendFixed

Ubuntu/Debian: E: Could not get lock /var/lib/dpkg/lock-frontend — 누가 쥐고 있고 어떻게 기다리는지

다른 패키지 관리자, 대개 부팅 때 persistent systemd 타이머로 발화한 Ubuntu 의 unattended-upgrades 가 여러분의 apt-get 이 도는 동안 dpkg 프런트엔드 락을 쥐고 있는 것입니다. Ubuntu 는 apt 바이너리에만 binary::apt::DPkg::Lock::Timeout "120" 을 실어 두어서 apt-get 은 즉시 포기하고 apt 는 기다립니다. 메시지의 PID 를 읽고, 실행이 끝나게 두거나 apt-get 에 -o DPkg::Lock::Timeout=<초> 를 주고, dpkg --configure -a 는 실제로 중단된 실행 뒤에만 쓰고, 락 파일은 절대 지우지 마세요. 보유자가 종료하면 커널이 푸는 fcntl 락입니다.

APT (Ubuntu/Debian)