できない.dev

Node.js で「EADDRINUSE: address already in use」が解消できない

EADDRINUSE は同じポートで他プロセスが LISTEN していることが原因。
lsof / netstat で占有プロセスを特定して終了するか、ポート番号を変更すれば解決する。

#eaddrinuse#port#listen#server

公開: 更新:

要約

Error: listen EADDRINUSE: address already in use :::3000 のエラーは、同じポートを既に別のプロセスが占有しているために発生する。lsof -i :3000 でプロセスを特定して終了する、もしくはポート番号を変更すれば解決する。

よくある原因

  1. 直前のプロセスが残っている: ターミナルで Ctrl+C を押したつもりが Node プロセスが孤児化して残っている。
  2. 別アプリが同ポートを使用している: 例えば 3000 は React dev サーバ、5432 は PostgreSQL など、他開発ツールとぶつかる。
  3. コンテナ / WSL のポートフォワード: Docker Desktop の published ports が解放されておらず、ホスト側の同番ポートを掴み続けている。
  4. TIME_WAIT 状態: 直前にサーバが落ちたあと、TCP が TIME_WAIT で数十秒〜数分占有を続ける。

解決策

1. 占有プロセスを探して終了する

macOS / Linux:

lsof -i :3000
# または
ss -ltnp | grep :3000
kill -9 <pid>

Windows (PowerShell / cmd):

netstat -ano | findstr :3000
taskkill /PID <pid> /F

Node.js のシステムエラー一覧 に EADDRINUSE の記載がある。

2. ポート番号を変える

環境変数で切り替える形にしておくと衝突時に楽。

const port = process.env.PORT ?? 0; // 0 を渡すと OS が空きポートを割り当てる
server.listen(port, () => {
  console.log("listening on", server.address().port);
});

0 を渡すと OS が任意の空きポートを選ぶので CI などで便利(net.Server.listen の公式ドキュメント を参照)。

3. Docker Desktop / WSL の再起動

ホストで別プロセスが見当たらないのに EADDRINUSE が出る場合、Docker / WSL のポートフォワードが残っていることが多い。
Docker Desktop を再起動するか、wsl --shutdown を実行する。

4. TIME_WAIT 状態の回避

短時間で再起動を繰り返すスクリプトでは、前回終了時に server.close() を確実に呼ぶか、ポート 0 を使い回す。
Linux なら net.ipv4.tcp_tw_reuse=1 で TIME_WAIT を再利用できる場合がある。

実行例

実際に上記の手順を node:20(Debian GNU/Linux 12 bookworm)環境で動かすと、PORT=3000 を二重に bind しようとした2つ目のプロセスが listen EADDRINUSE: address already in use :::3000 を出力して終了コード 1 で終了し、PORT=3001 に切り替えた3つ目のプロセスは終了コード 0 で正常に起動したことが確認できる。

== versions ==
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
v20.20.2
Python 3.11.2
git version 2.39.5
 
                                                                               
                This is not the tsc command you are looking for                
                                                                               
 
To get access to the TypeScript compiler, tsc, from the command line either:
 
- Use npm install typescript to first add TypeScript to your project before using npx
- Use yarn to avoid accidentally running code from un-installed packages
v10.4.1
== run ==
--- 1 つ目のサーバを PORT=3000 でバックグラウンド起動 ---
listening on 3000
--- 2 つ目のサーバを同じ PORT=3000 で起動 (EADDRINUSE を想定)---
listen error: EADDRINUSE listen EADDRINUSE: address already in use :::3000
2 つ目の終了コード: 1
--- 解消: 別ポート (PORT=3001) で再起動 ---
listening on 3001
別ポートの終了コード: 0
--- 1 つ目(バックグラウンド)の終了を待つ ---
1 つ目の終了コード: 0

— 2026-06-02 時点の出力

この記事は役立ちましたか?