エラーメッセージの意味:なぜ address already in use が出るのか
Clash および Clash Meta(mihomo)カーネルをベースとするクライアントは起動時、設定ファイルで指定されたいくつかのポートを監視しようとします。混合ポート(mixed-port、HTTP と SOCKS5 の両方のリクエストを受け付ける)、独立した HTTP ポート(port)と SOCKS5 ポート(socks-port)、さらに一部のクライアントは RESTful API ポート(external-controller、デフォルトは 9090 が一般的)も監視します。このうちいずれかのポートがシステム内の別のプロセスに既に使用されている場合、カーネルはバインド(bind)処理に失敗し、ログやポップアップに次のようなメッセージが表示されます:
panic: listen tcp 127.0.0.1:7890: bind: address already in use
このエラーメッセージ自体が問題を明確に示しています。カーネルが 7890 ポートを監視しようとしたものの、OS がそれを拒否した、つまりそのポートは既に「使用中」ということです。この種の問題は設定ファイルの記述ミスでも、サブスクリプションやプロキシノードの問題でもなく、純粋にローカルマシン上のポート競合です。対処の流れは常に2ステップです:まずポートを占有しているプロセスを特定し、次に「そのプロセスを停止する」か「Clash 側で別のポートに切り替える」かを判断します。
Clash 系クライアントを2つ同時にインストールしている場合(例:Clash Verge Rev と ClashX Meta)、両方をスタートアップ起動に設定していると、ほぼ必ずデフォルトポートを取り合うことになります。この場合はポートを何度も変更するより、いずれか一方をアンインストールまたは完全に無効化する方が確実です。
Windows:netstat と PowerShell でポート占有プロセスを特定する
Windows で最も直接的な方法は、コマンドプロンプトまたは PowerShell を開いて netstat でポートに対応するプロセス ID(PID)を確認し、タスクマネージャーまたは taskkill で該当プロセスを終了することです。デフォルトの 7890 ポートを例にすると:
netstat -ano | findstr :7890
出力の最後の列が PID です。例えば 12480 と表示された場合、次を実行します:
tasklist | findstr 12480
これでどの実行ファイルがこのポートを占有しているか確認できます。このプロセスを終了しても問題ないと確認できたら、直接終了させます:
taskkill /PID 12480 /F
PowerShell ユーザーは、1つのコマンドでポートに対応するプロセス名を直接取得することもでき、より分かりやすい情報が得られます:
Get-Process -Id (Get-NetTCPConnection -LocalPort 7890).OwningProcess
よくある占有の原因には、前回 Clash クライアントが異常終了した際に残ったバックグラウンドプロセス(特にタスクマネージャーでウィンドウを強制終了しても、カーネルプロセスが一緒に終了していない場合)、他の Clash カーネルベースのツール、一部のダウンロードツールやローカルプロキシデバッグツールがデフォルトで 7890 付近のポート帯を使用しているケースなどが挙げられます。
macOS:lsof でポート占有を確認する
macOS で最も一般的なのは lsof(list open files)です。これはポート番号から占有プロセスを逆引きできます:
sudo lsof -i :7890
出力の COMMAND 列がプロセス名、PID 列がプロセス番号です。確認後、プロセスを終了させます:
kill -9 対応するPID
netstat に慣れている場合、macOS でも互換の記法は残っていますが、情報が完全な lsof を直接使うことをおすすめします。また、ClashX や ClashX Meta のようなメニューバー型クライアントは、メニューバーのアイコンを終了させても、バックグラウンドのコアプロセスが必ずしも同時に終了するわけではない点に注意が必要です。ポート競合が発生した場合は、まずコアプロセスが実際に終了しているかを確認し、画面だけを閉じていないか見直してください。
ps aux | grep -i clash
このコマンドで現在のシステム内にある clash 関連のプロセスをすべて一覧表示できるため、残留プロセスを一括で確認するのに便利です。
Linux:ss と fuser でプロセスを特定・終了する
比較的新しいディストリビューションでは、徐々に廃止が進んでいる netstat の代わりに ss を使うことが推奨されています:
sudo ss -tulnp | grep 7890
出力の users:(("プロセス名",pid=1234,...)) の部分が占有情報です。より簡潔な fuser を使って直接特定・終了することもできます:
sudo fuser -k 7890/tcp
このコマンドは 7890 ポートを占有しているプロセスを直接終了させます。占有元が安全に終了できる古いプロセスであると確認できている場合に適しています。systemd で mihomo や clash サービスを管理している場合、より確実な方法は、まず同一ポートを監視しようとするサービスインスタンスが2つ同時に起動していないか確認することです:
systemctl status mihomo
systemctl status clash
両方のサービスが動作していて、両方が同じポートを監視しようとしている場合は、ポート変更で「回避」するのではなく、いずれか一方を停止するべきです。そうしないと、ルールやサブスクリプション更新などの機能が2つのプロセスに分裂し、状態が不整合になり、原因調査がさらに難しくなります。
Clash 設定ファイルの混合ポートを変更する
ポートを占有しているプログラムを簡単に停止できない場合(システムサービスや長期間使用中の別ツールなど)、Clash 側で別のポートに切り替える方がシンプルです。Clash Meta(mihomo)カーネルでは、混合ポートのフィールドを直接使うことを推奨しています:
mixed-port: 7895
allow-lan: false
bind-address: "*"
external-controller: 127.0.0.1:9096
secret: ""
mixed-port の値をデフォルトの 7890 から未使用のポート(10000 以上で、一般的なソフトウェアと衝突しない番号帯、例:7895、17890 などがおすすめ)に変更し、保存後にクライアントを再起動するだけです。旧式の port(HTTP)と socks-port(SOCKS5)フィールドを mixed-port の代わりに使っている場合も、競合がないか併せて確認してください:
port: 7891
socks-port: 7892
external-controller: 127.0.0.1:9097
external-controller(RESTful API ポート、デフォルトは一般的に 9090)も同様にポートを占有します。Clash パネル(Dashboard)が開かず、エラーメッセージに 9090 が表示されている場合は、原理と対処法は 7890 の場合と完全に同じで、変更するフィールドが異なるだけです。
多くの GUI クライアント(Clash Verge Rev、Clash Plus、FlClash など)も、設定画面でポート番号を直接入力する項目を用意しており、設定ファイルの対応フィールドを変更するのと同じ効果があります。変更後は同様にコアまたはクライアントを再起動しないと反映されません。ポートを変更した後は、システムプロキシの設定やブラウザ拡張機能に入力しているポート番号も忘れずに更新してください。そうしないと「クライアントは正常に動作しているのに、ブラウザからは接続できない」という状況が発生します——これはポート競合そのものの問題ではなく、ポートを変更した後にシステムプロキシ側が追従していないためです。
よくある占有の原因と回避のポイント
これまでの報告を整理すると、7890 付近のポート帯で最も多い競合の原因は以下のとおりです。事前に把握しておくと調査の手間を1段階省けます:
- 前回の Clash プロセスが完全に終了していない:右上のウィンドウを閉じるだけでは、コアプロセスがバックグラウンドで動作を続けている場合があり、再起動すると自分自身とポートを取り合ってしまいます。
- 複数の Clash 系クライアントを同時にインストールしている:例えばパソコンに Clash Verge Rev と旧版 Clash for Windows の残留物が両方あり、両方がスタートアップ起動に設定されていると衝突しやすくなります。
- 他のプロキシ/デバッグツール:一部のローカル開発用デバッグプロキシツールやパケットキャプチャツールも、デフォルトで 7890 やその近隣のポートを監視することがあります。
- コンテナや仮想化環境のポート転送:Docker や仮想マシンでポートマッピングを行う際、コンテナ内のサービスがホスト側のちょうどこの範囲のポートにマッピングされることがあります。
回避のポイントはシンプルです:使用中の Clash 系クライアントは1つだけに絞り、他のスタートアップ起動項目はアンインストールまたは完全に無効化してください。複数のプロキシツールを並行して使う必要がある場合は、エラーが出てから場当たり的に変更するのではなく、事前に各ツールで重複しないポート範囲を計画しておきましょう。
よくある質問
ポートを変更したのに、クライアントがまだポート使用中と表示するのはなぜですか?
まず設定ファイルの保存先パスと、クライアントが実際に読み込んでいる設定ファイルが同一のものか確認してください。一部のクライアントは複数設定の切り替えに対応しているため、変更したのが現在有効になっているファイルではない可能性があります。また、新しく設定したポートが別のサービスと重複していないかも確認が必要です。より使われにくい4桁または5桁のポート番号に変更し、前述のコマンドで再度そのポートが空いているか確認してください。
ポートを占有しているプロセスを終了させても安全ですか?システムに影響はありますか?
占有元が残留した Clash プロセスや、再起動可能な通常のアプリケーションであると確認できれば、終了させても安全です。しかし lsof/netstat の結果、占有元がシステムレベルのサービスや見覚えのないプロセスだった場合は、まずそのプロセス名を検索して用途を確認するか、システムサービスを誤って停止するリスクを避けるために Clash 側のポートを変更する方法を選ぶことをおすすめします。
モバイル端末(Android/iOS)でもポート占有の問題は発生しますか?
モバイル端末のサンドボックス機構はより厳格で、ポート競合は主に複数の VPN/プロキシ系アプリを同時に動かした場合に発生します。システムは通常、一度に1つの VPN 設定しか有効化を許可しません。接続に失敗した場合は、他のプロキシ系アプリがバックグラウンドで VPN サービスを実行していないか確認し、いずれかを停止すれば解決します。処理の考え方はデスクトップ環境より簡単です。