開発サーバー起動時の「Address already in use」エラーとポート解放の対処法

に公開

はじめに

Next.jsやViteなどの開発サーバーを起動しようとした際、以下のような Address already in use (EADDRINUSE) エラーに遭遇することがある。

エラー出力例
Error: listen EADDRINUSE: address already in use :::3000
    at Server.setupListenHandle [as _listen2] (node:net:1883:21)
    at listenInCluster (node:net:1948:12)
    at Server.listen (node:net:2047:7)
    ...

これは、指定したポート(この例では 3000)が既に他のプロセスによって使用されているために発生する。
本記事では、この問題の原因と、OSごとの解決策を備忘録としてまとめる。

対象環境

  • macOS
    • OS: macOS Sequoia 15.6
    • シェル: Zsh
    • ツール: lsof, kill
  • Windows
    • OS: Windows 11 Pro 23H2
    • シェル: PowerShell 7.4.2
    • ツール: netstat, taskkill
  • Linux
    • OS: Ubuntu 22.04.4 LTS
    • シェル: Bash 5.1.16
    • ツール: lsof, kill

原因

Address already in use エラーの主な原因は、指定されたネットワークポートが他のアプリケーションやプロセスによって占有されていることである。開発中によくあるシナリオは以下の通りである。

  • 以前に起動した開発サーバーが、ターミナルを閉じても正常に終了せず、バックグラウンドで動作し続けている。
  • 別のプロジェクトの開発サーバーが、同じポート番号を使用して起動している。
  • 開発用ツールとは無関係の別のアプリケーションが、偶然同じポートを使用している。

解決するには、該当ポートを使用しているプロセスを特定し、それを終了させる必要がある。

解決策

ポートを解放するための手順は、OSによって使用するコマンドが異なる。ここでは、macOS/LinuxとWindowsのそれぞれについて解説する。

macOS / Linux の場合

macOSやLinuxベースのシステムでは、lsof (List Open Files) コマンドと kill コマンドを組み合わせて使用する。

ステップ1: ポートを使用しているプロセスを特定する (lsof)

lsof コマンドに -i オプションとポート番号を指定することで、そのポートを使用しているプロセスを特定できる。ここではポート 3000 を例とする。

ターミナル
lsof -i :3000

コマンドを実行すると、以下のような出力が得られる。

実行結果例
COMMAND   PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node    12345 myuser   25u  IPv6 0x123456789abcdef0      0t0  TCP *:3000 (LISTEN)

この出力から、以下の情報がわかる。

  • COMMAND: プロセスのコマンド名 (ここでは node)
  • PID: プロセスID (ここでは 12345)

この PID が、プロセスを終了させるために必要な情報となる。

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

次に、特定した PID を使って kill コマンドを実行し、プロセスを終了させる。

ターミナル
kill 12345

これにより、プロセスに終了シグナル (SIGTERM) が送られ、プロセスは安全に終了処理を行う。コマンド実行後、何も出力がなければ成功である。

Windows の場合

Windowsでは、netstat コマンドと taskkill コマンドを組み合わせて使用する。

ステップ1: ポートを使用しているプロセスを特定する (netstat)

netstat コマンドは、ネットワーク接続や統計情報を表示するコマンドである。-ano オプションを付けて実行し、その結果を findstr でフィルタリングすることで、特定のポートを使用しているプロセスを見つけ出す。

PowerShell
netstat -ano | findstr ":3000"

コマンドを実行すると、以下のような出力が得られる。

実行結果例
  TCP    0.0.0.0:3000           0.0.0.0:0              LISTENING       23456
  TCP    [::]:3000              [::]:0                 LISTENING       23456

出力の最後の列にある数字が、プロセスID (PID) である (この例では 23456)。

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

特定した PID を使って taskkill コマンドでプロセスを終了させる。/F オプションはプロセスの強制終了を意味する。

PowerShell
taskkill /F /PID 23456

実行後、以下のような成功メッセージが表示されれば、プロセスの終了は完了である。

実行結果例
SUCCESS: The process with PID 23456 has been terminated.

以上の手順でポートが解放され、再度開発サーバーを起動できるようになる。

おわりに

開発中に頻繁に遭遇する Address already in use エラーは、本記事で紹介した手順で迅速に解決できる。OSごとにコマンドは異なるものの、やっていることは「ポートを占有しているプロセスを特定し、終了させる」という点で共通している。
この備忘録が、同様の問題に直面した開発者の助けとなれば幸いである。

参考リンク

Discussion