Node.jsサーバー起動時の「EADDRINUSE: address already in use」エラーの修正方法

beginner💚 Node.js2026-03-18| Node.js(全バージョン)、macOS / Linux / Windows

Error Message

Error: listen EADDRINUSE: address already in use :::3000
#Node.js#EADDRINUSE#ポート

エラーの内容

Error: listen EADDRINUSE: address already in use :::3000
    at Server.setupListenHandle [as _listen2] (node:net:1739:16)
    at listenInCluster (node:net:1787:12)
    at Server.listen (node:net:1875:7)
    at Function.listen (/app/node_modules/express/lib/application.js:635:24)

ポート 3000 がすでに使用中です。Node.js がそのポートにリスナーをバインドしようとしたところ、別のプロセスがすでに起動していたため、処理を中断しました。同一のTCPポートを2つのプロセスが共有することはできないため、どちらか一方を終了させる必要があります。

原因

よくある原因は3つあります:

  • 以前のサーバーインスタンスがクラッシュした、またはターミナルウィンドウを強制終了した。Node.js プロセスがバックグラウンドで動き続け、ポート 3000 を保持したままになっている。
  • 別のプロセスがすでにそのポートを使用している — 別の Node.js アプリ、Webpack dev server、Python Flask アプリなど、さまざまな可能性がある。
  • 再起動が早すぎた。旧プロセスが終了した後、OSがポートを解放するまでに少し時間(通常は数秒)が必要です。Ctrl+C の直後に npm start を実行すると、その猶予時間より早く起動しようとしてしまうことがある。

手順を追った解決方法

ステップ1:ポートを使用しているプロセスを見つける

macOS / Linux の場合:

lsof -i :3000

出力例:

COMMAND   PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node     1234  alice   23u  IPv6  12345      0t0  TCP *:3000 (LISTEN)

PID 列の値(ここでは 1234)が、次のステップで必要になります。

ss や netstat を使う場合も同様に使えます:

# ss を使う場合
ss -tlnp | grep :3000

# netstat を使う場合
netstat -tlnp | grep :3000

Windows(コマンドプロンプトまたは PowerShell)の場合:

netstat -ano | findstr :3000

出力例:

TCP    0.0.0.0:3000    0.0.0.0:0    LISTENING    5678

最後の数字(5678)が PID です。

ステップ2:プロセスを終了する

macOS / Linux の場合:

kill -9 1234

1234 の部分を実際に確認した PID に置き換えてください。あるいは、調べる手間を省いて一発で実行することもできます:

kill -9 $(lsof -ti :3000)

Windows(管理者として実行)の場合:

taskkill /PID 5678 /F

ステップ3:Node.js サーバーを再起動する

node app.js
# または
npm start
# または
npx ts-node src/index.ts

別の解決策:別のポートを使う

ポート 3000 を使用しているプロセスが意図的なもので、そのアプリも動かしておく必要がある場合は、サーバーを別のポートに移動するだけで解決します。

アプリのコードを変更する場合:

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`サーバーがポート ${PORT} で起動しました`);
});

コードを変更せずに起動時にポートを指定する場合:

PORT=3001 node app.js

Windows の場合:

set PORT=3001 && node app.js

nodemon / 開発用ウォッチモードでの解決方法

ファイルを保存するたびにこのエラーが発生する場合、nodemon がOSのポート解放前にプロセスを再起動している可能性があります。1秒の遅延を設定するだけで通常は解決します:

# nodemon.json
{
  "delay": 1000
}

それでも解決しない場合は、すべての Node プロセスを強制終了してからやり直してください:

# macOS / Linux — 全 Node プロセスを終了
pkill -f node

# その後、再起動
npm run dev

修正の確認方法

プロセスを終了した後、同じ検索コマンドを実行して確認します:

# macOS / Linux
lsof -i :3000

# Windows
netstat -ano | findstr :3000

何も出力されなければ、ポートは解放されています。サーバーを起動すれば、問題なく立ち上がるはずです。

実際に応答しているか確認したい場合は、curl で簡単にテストできます:

curl http://localhost:3000
# またはブラウザで http://localhost:3000 を開く

このエラーを防ぐためのヒント

  • ターミナルを閉じるより Ctrl+C を使う — ウィンドウを閉じると Node.js プロセスが孤立したまま残ることがよくあります。プロセスは動き続け、ポートを占有し続けます。Ctrl+C は SIGINT を送信し、正しく終了処理を行います。
  • ポートは環境変数から読み込む3000 のハードコードは問題が起きるまでは便利ですが、process.env.PORT || 3000 にしておけば、コードを編集せずに環境変数一つでポートを切り替えられます。
  • 本番環境ではグレースフルシャットダウンハンドラを追加する — これにより、終了時にサーバーがポートを正しく解放できます:
process.on('SIGTERM', () => {
  server.close(() => {
    console.log('サーバーを終了しました');
    process.exit(0);
  });
});
  • PM2 を使う場合は古いインスタンスに注意するpm2 restart app はオーバーラップを自動で処理します。クリーンな状態から始めたい場合は、まず pm2 stop all を実行して、ポートを占有しているプロセスが残っていないことを確認してください。

Related Error Notes