まず競合しているポートを特定する
「address already in use」「bind failed」「ポートはすでに使用されています」と表示された場合、原因はおおむね明確です。Mihomoのコアがローカルポートの待ち受けを開始しようとしたものの、そのポートを別のプロセスが使用しています。競合しやすいのは 7890 ですが、7891、9090、または設定で指定した任意のポートの場合もあります。
mixed-port は混合プロキシポートです。1つの待ち受け口でHTTPプロキシとSOCKS5プロキシの接続を受け付けられます。多くのClashクライアントでは初期値が 7890 です。ブラウザー拡張、システムプロキシ、コマンドラインツールは通常このポートに接続するため、競合するとコアの起動に失敗したり、プロキシに接続できなくなったりします。
| 設定項目 | 代表的なポート | 用途 | mixed-portと重複可能か |
|---|---|---|---|
mixed-port |
7890 | HTTPとSOCKS5の両方を受け付ける | 1つのプロセスだけが待ち受け可能 |
port |
7890 | HTTPプロキシのみを提供 | 同じ待ち受けアドレスとポートは使用不可 |
socks-port |
7891 | SOCKS5プロキシのみを提供 | 同じ待ち受けアドレスとポートは使用不可 |
external-controller |
9090 | 制御インターフェースを提供し、通常のプロキシ通信は扱わない | 専用ポートを使用する |
ログから正確なポートを確認する
まずクライアントのログ画面を開き、bind、listen、address already in use、または端口を検索します。ログにlisten tcp 127.0.0.1:7890と表示されている場合は、TCP 7890を確認します。0.0.0.0:7890と表示されている場合は、プログラムがローカルマシンのすべてのネットワークインターフェースでこのポートを待ち受けようとしていることを示します。そのため、127.0.0.1だけで待ち受ける場合よりも競合範囲が広くなります。
同じ設定ファイルに mixed-port: 7890 と port: 7890 が同時に記載されていないかも確認します。この場合、外部プログラムを探す必要はありません。設定自体が2つの待ち受けに同じアドレスを使わせています。混合ポートを残し、不要な独立HTTPポートまたはSOCKSポートを削除してください。
Windowsでnetstatを使って7890の使用プロセスを特定する
Windows 10とWindows 11では、標準搭載の netstat を利用できます。現在のClashクライアントを完全に終了してから、「ターミナル」または「コマンドプロンプト」を管理者として開き、次のコマンドを実行します。
netstat -ano | findstr :7890
典型的な結果は次のとおりです。最後の列にある 16420 はプロセス識別子、つまりPIDです。
TCP 127.0.0.1:7890 0.0.0.0:0 LISTENING 16420
状態が LISTENING の行だけが、プログラムがそのTCPポートを待ち受けていることを示します。結果がリモートアドレスに :7890 を含むだけなら、ローカルポートが使用中だとは判断できません。「ローカル アドレス」列が 127.0.0.1:7890、0.0.0.0:7890、または [::]:7890 になっているかを重点的に確認してください。
PIDからプログラム名を確認する
PIDを取得したら、続けて次を実行します。
tasklist /FI "PID eq 16420"
PowerShellでは、プログラムのパスも確認できます。
Get-Process -Id 16420
Get-CimInstance Win32_Process -Filter "ProcessId = 16420" |
Select-Object ProcessId, Name, ExecutablePath, CommandLine
別のClash、Mihomo、sing-box、またはプロキシクライアントだった場合、画面を閉じても古いコアが終了していない可能性があります。まずそのクライアントのメニューから通常の手順で終了し、3〜5秒待ってからポートを再確認してください。タスクマネージャーでウィンドウを閉じるだけでは、バックグラウンドのコアが終了するとは限りません。通知領域に実行中のアイコンが残っていることもあります。
プロセスを終了してよいと確認できたら、タスクマネージャーの「詳細」タブでPIDを検索するか、次を実行します。
taskkill /PID 16420 /F
netstatに結果がないのにエラーが出る場合
- ログに記録されたポートが本当に
7890か確認してください。制御ポート9090を混合ポートと取り違えないようにします。 - IPv4とIPv6の両方を確認します。
[::]:7890で待ち受けるプログラムが、別のプロセスによるIPv4アドレスへのバインドを妨げる場合があります。 - クライアントを終了してからコマンドを再実行し、現在のクライアントによる正常な待ち受けを競合と誤認しないようにします。
- ポータブル版とインストール版を同時にスタートアップへ登録するなど、クライアントがコアを2つ起動していないか確認します。
- ログに権限不足が実際に表示されていないか確認します。権限エラーとポート競合では対処方法が異なります。
macOSでlsofを使って待ち受けプログラムを探す
macOSでは lsof を使って、TCP 7890を開いているプロセスを確認できます。「ターミナル」を開き、次を実行します。
sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
-nP はアドレスとポートを数値で直接表示し、名前解決による遅延を避けます。結果の COMMAND はプロセス名、PID はプロセス番号です。例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mihomo 8421 user 10u IPv4 0t0 TCP 127.0.0.1:7890 (LISTEN)
次のコマンドで起動引数を確認し、どのクライアントに属するプロセスか判断します。
ps -p 8421 -o pid,ppid,user,command
別のプロキシクライアントのプロセスだった場合は、まずメニューバーのアイコンから通常の手順で終了してください。プロセスが応答しなくなったことを確認したら、最初に通常の終了シグナルを送ります。
kill 8421
数秒待ってから lsof を再実行します。通常の終了が効かない場合に限り、kill -9 8421 を検討してください。強制終了すると現在の設定が保存されない可能性があるため、最初に行うべきではありません。
独立したSOCKSポートも確認する
設定で socks-port: 7891 も有効にしている場合は、7890と7891を個別に確認します。混合ポートを7892に変更しても、別の待ち受けが7891で競合している問題は解決しません。
sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
sudo lsof -nP -iTCP:7891 -sTCP:LISTEN
sudo lsof -nP -iTCP:9090 -sTCP:LISTEN
Linuxでssを使ってポートの待ち受けを確認する
現在のLinuxディストリビューションの多くには ss が標準で用意されています。待ち受けソケットと対応するプロセスを直接表示できます。次を実行します。
sudo ss -ltnp 'sport = :7890'
オプションの l は待ち受け状態のみ、t はTCP、n はポートを数値で直接表示、p はプロセスを表示する指定です。互換性が高く、より分かりやすい絞り込み方法も使えます。
sudo ss -ltnp | grep ':7890'
結果は次のようになります。
LISTEN 0 4096 127.0.0.1:7890 0.0.0.0:* users:(("mihomo",pid=2317,fd=8))
Mihomoをsystemdで管理している場合、kill だけでプロセスを終了しないでください。サービスマネージャーが直ちに再起動する可能性があります。まずサービスの状態を確認し、該当するユニットを停止します。
systemctl --type=service --state=running | grep -Ei 'mihomo|clash'
sudo systemctl status mihomo
sudo systemctl stop mihomo
コンテナ環境ではポートマッピングも確認します。ホスト上のDockerまたはPodmanのプロキシプロセスが7890を使用していると、コンテナ内にMihomoという名前のホストプロセスがなくても競合することがあります。
docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Ports}}'
podman ps --format 'table {{.ID}}\t{{.Names}}\t{{.Ports}}'
mixed-portとクライアントの待ち受けポートを変更する
7890を使用しているプログラムを残す必要がある場合、ClashまたはMihomoを未使用のポート、たとえば 7892 に切り替えるのが最も確実です。前述のシステムコマンドで7892に待ち受けがないことを確認してから、クライアントを変更してください。
グラフィカルインターフェースから変更する
グラフィカルインターフェースを備えたクライアントでは通常、「設定」→「詳細設定」→「混合ポート」から変更できます。7890 を 7892 に変更して保存し、コアを再起動します。クライアントによってメニュー名は「Mixed Port」「混合プロキシポート」「ポート設定」など異なりますが、変更対象はいずれも現在のコアの mixed-port です。
画面にHTTPポート、SOCKSポート、混合ポートが同時に表示される場合、複数の項目に同じ値を設定しないでください。入口を1つに絞るなら、混合ポートを有効にして不要な独立待ち受けを無効にすると、競合箇所を減らせます。
YAML設定を直接編集する
設定ファイルで次のように項目を変更します。
mixed-port: 7892
allow-lan: false
mode: rule
log-level: info
mixed-port は整数で指定する必要があり、コロン付きのアドレスにはできません。また、同じ設定内の port、socks-port、制御インターフェースと重複させないでください。保存後はコアに設定を再読み込みさせる必要があります。ディスク上のファイルを変更しただけでは、実行中の待ち受けは自動で変わりません。
複数のProfileを使っている場合は、現在有効な設定を編集しているか確認します。クライアントによっては購読内容をアプリデータフォルダーへコピーするため、購読元ファイルと実行時設定は同一ではありません。まず画面で現在のProfile名を確認し、その設定の編集画面から開いて、未使用のコピーを変更しないようにします。
新しいポートが待ち受けていることを確認する
コアを再起動したら、すぐにウェブページが開くかだけを確認しないでください。まずシステムに新しい待ち受けが現れ、古いポートが現在のクライアントに使われていないことを確認します。
# Windows
netstat -ano | findstr :7892
# macOS
sudo lsof -nP -iTCP:7892 -sTCP:LISTEN
# Linux
sudo ss -ltnp 'sport = :7892'
期待される結果は、ローカルアドレス 127.0.0.1:7892 またはクライアントで明示した待ち受けアドレスが LISTEN 状態になることです。LAN接続を許可している場合は 0.0.0.0:7892 と表示されることがあります。その場合はアクセス制御とファイアウォール規則も確認し、ローカルの競合を解消するためだけに待ち受け範囲を広げないでください。
システムプロキシとアプリのプロキシを同期する
ポートを変更してもウェブページが開けない場合、システムプロキシが古い 127.0.0.1:7890 を指したままになっていることが最も一般的です。コアは7892で正常に動作していても、ブラウザーが7890へ接続し続けるため、「変更が反映されていない」ように見えます。
まずクライアントにシステムプロキシを再設定させる
- クライアントの「システムプロキシ」スイッチをオフにします。
- 混合ポートが
7892で保存されていることを確認し、コアを再起動します。 - 「システムプロキシ」を再びオンにします。
- OSのプロキシ設定画面を開き、アドレスが
127.0.0.1、ポートが7892になっていることを確認します。
Windows 11では「設定」→「ネットワークとインターネット」→「プロキシ」で手動プロキシサーバーを確認できます。macOSでは「システム設定」→「ネットワーク」→現在のネットワーク→「詳細」→「プロキシ」でWebプロキシまたはセキュアWebプロキシを確認します。通常はクライアントにこれらの項目を管理させるのが安全です。手動で入力する場合は、実際の待ち受けポートと必ず一致させてください。
ブラウザー拡張とコマンドライン変数を確認する
プロキシ切り替え拡張機能はシステム設定を介さず、古いポートを使い続けることがあります。拡張機能のプロキシ設定でHTTPまたはSOCKS5のポートを7892に変更してください。開発ツールが環境変数でプロキシを指定している場合もあるため、次を個別に確認します。
HTTP_PROXY=http://127.0.0.1:7892
HTTPS_PROXY=http://127.0.0.1:7892
ALL_PROXY=socks5://127.0.0.1:7892
同じ mixed-port で上記2種類のプロトコルを受け付けられますが、アプリに指定するプロトコル接頭辞は正しく設定する必要があります。独立した socks-port を設定している場合、ALL_PROXY はその独立ポートを指定し、混合ポートを機械的に指定しないでください。
TUNモードの違い
TUNモードは仮想ネットワークインターフェースを通じて通信を引き受けるため、通常はシステムのHTTPプロキシスイッチに依存しません。ただし、設定でMihomoに mixed-port: 7890 の作成を要求している限り、7890が使用中だとコアの起動に失敗する可能性があります。競合プロセスを終了するか、待ち受けポートを変更するという対処は変わりません。
切り分け中は、一度に1種類の通信経路だけを残すことをおすすめします。TUNを無効にしてシステムプロキシで7892を確認するか、システムプロキシを無効にしてTUNだけを確認してください。両方を同時に有効にすると変数が増え、DNS、ルーティング、ブラウザー拡張の問題をポート競合と誤認しやすくなります。
変更後も使用中と表示される場合の確認手順
ポートを7892に変更したのにログで7890の使用中エラーが続く場合、実行時設定に変更内容が反映されていません。次の順に確認すれば、設定・プロセス・システムプロキシのどこで同期が途切れているかをすばやく特定できます。
- 最新のログを読み直す。エラーの発生時刻が今回の再起動後であることを確認し、ログに記録された完全なアドレスとポートを書き留めます。
- 現在のProfileを確認する。クライアントで現在選択されている設定名を確認し、テスト用設定を編集したまま購読設定を実行していないか確認します。
- 設定を再読み込みする。YAMLを保存したら、クライアントの「設定を再読み込み」または「コアを再起動」を実行します。設定画面を閉じるだけでは不十分です。
- 重複したクライアントを確認する。通知領域、メニューバー、スタートアップ項目、systemdサービス、コンテナを確認し、2つ目のコアが起動していないことを確認します。
- 項目の重複を確認する。
mixed-port、port、socks-port、external-controllerが同じアドレスとポートを使用していないことを確認します。 - 新しいポートの待ち受けを確認する。クライアント画面の「実行中」表示だけでなく、netstat、lsof、ssで7892を検証します。
- すべてのプロキシ接続先を同期する。システムプロキシ、ブラウザー拡張、ターミナルの環境変数、開発ツール、LAN内の端末に残る古いポートを更新します。
curlで最終確認する
7892が正常に待ち受けていることを確認したら、curl から混合ポートを明示してリクエストを送信できます。次のコマンドで接続過程とHTTPレスポンスヘッダーを表示します。
curl -I -v -x http://127.0.0.1:7892 https://example.com
出力にはまず 127.0.0.1:7892 への接続が表示され、その後、対象サイトへのCONNECTトンネルが確立されます。Connection refused と表示された場合、そのアドレスには利用可能な待ち受けがありません。接続できても対象へのリクエストがタイムアウトする場合、ポート競合は解決済みです。次にノード、ルール、DNS、ネットワーク接続を確認してください。
再利用できる対処の要点
- ログに
address already in useと出たら、まず待ち受けプロセスを確認し、先にノードを変更しない。 - 古いプロキシプログラムが7890を使用している:古いプログラムを終了し、重複した自動起動を整理する。
- 使用中のプログラムを残す必要がある:
mixed-portを7892など、空いていることを確認したポートに変更する。 - コアが新しいポートで待ち受けているのにアプリがインターネットへ接続できない:システムプロキシとアプリ内プロキシを同期して変更する。
- 購読更新後に問題が再発する:ポート変更をクライアントの永続的な上書き設定に登録する。
- TUNを有効にしても起動に失敗する:設定内の混合ポートと制御ポートが競合していないか確認する。