まずログを確認:7890はプロキシ用、9090はコントロール用

Clashやmihomoコアを使用するクライアントが起動しない場合は、まずコアのログを開き、listen、bind、具体的なアドレスを含むエラー行を探します。address already in useと表示される場合、通常はそのアドレスとポートを別のプロセスがすでに待ち受けています。Windowsでは「通常、各ソケット アドレスは 1 回のみ使用できます」と表示されることもあります。ポート、バインド先アドレス、プロトコルを記録してから、プロセスを停止するか設定を変更するか判断しましょう。

7890と9090はよく使われる設定値ですが、すべてのクライアントで固定されているわけではありません。実際の接続先は、現在有効な設定と起動ログで確認してください。用途の異なるポートなので、エラーが出たからといって一律にすべて変更する必要はありません。

設定項目設定例用途と影響
mixed-port7890同じポートでHTTPプロキシとSOCKS5接続を受け付けます。ブラウザー、ターミナル、システムプロキシなどが使用します。
external-controller127.0.0.1:9090クライアントやWebパネルから状態確認やプロキシ設定の切り替えを行うためのAPIです。Webプロキシの接続先ではありません。
port7892HTTPプロキシ専用の接続先です。この項目を有効にしている場合のみ確認してください。
socks-port7893SOCKS専用の接続先です。mixed-portだけを変更しても、このポートまで変わるとは限りません。

Windows:netstatとPowerShellで使用中のプロセスを特定

手順1:ポート番号だけでなく、待ち受け状態を確認

PowerShellを開き、次の2つのコマンドを実行します。出力の「ローカル アドレス」が対象ポートで終わり、状態がLISTENINGになっていることを確認してください。最後の列に表示されるのはプロセスID(PID)です。7890だけで検索すると、リモートアドレスや別のポート番号に一致する場合があります。列全体を確認しましょう。

netstat -ano -p tcp | findstr ":7890"
netstat -ano -p tcp | findstr ":9090"

PowerShellでローカルポートを指定して待ち受け中のプロセスを検索すれば、確立済みの接続をポート競合と誤認せずに済みます。

Get-NetTCPConnection -State Listen -LocalPort 7890,9090 -ErrorAction SilentlyContinue |
  Select-Object LocalAddress,LocalPort,OwningProcess

127.0.0.1:7890はIPv4のループバックアドレスでの待ち受け、0.0.0.0:7890はすべてのIPv4インターフェースでの待ち受けを示します。後者が使われている場合、通常、別のプログラムが同じポートを待ち受けることはできません。IPv6の[::]:7890がIPv4にも影響するかどうかは、ソケットの設定によって異なります。調査時はIPv6の出力も確認してください。

手順2:実行ファイルのパスを確認し、重複したプロセスを終了

以下ではPID 1234を使って確認方法を説明します。実際に実行するときは、直前のコマンド出力にあるPIDに置き換えてください。PIDはプロセスの再起動で変わるため、例の番号をそのまま使って終了しないでください。

tasklist /FI "PID eq 1234"
Get-Process -Id 1234 | Select-Object Id,ProcessName,Path
  • 別のプロキシクライアント:システムトレイから終了し、自動起動やコアの自動起動も無効にしてから、使用するクライアントを起動します。
  • 同じクライアントのバックグラウンドコア:ウィンドウを閉じても、トレイに最小化されるだけの場合があります。トレイの終了操作を使い、ポートの待ち受けが終了したことを確認してください。
  • サービスとして管理されているプロセス:どのサービスに属するかを確認し、該当するクライアントまたは「サービス」管理ツールから停止します。子プロセスだけを終了しても、監視プロセスがすぐに再起動する場合があります。
  • ほかの開発ツール:使用中のサービスがポートを占有している場合は、そのサービスを止めずにClash側のポートを変更するのが適切です。

実行ファイルのパスを確認する際に権限エラーが出た場合は、管理者としてターミナルを起動し直してください。プロセス名が似ているだけでシステムサービスを終了しないでください。また、「管理者として実行」しても、別のプロセスが使用中のポートは解放されません。

macOS・Linux:lsofまたはssで待ち受けプロセスを確認

macOSでは「ターミナル」からlsofを実行します。Linuxでもインストール済みであれば同じコマンドを使えます。-nPはアドレスとポートを数値で表示し、-sTCP:LISTENはTCPの待ち受けだけを表示するため、PIDとプロセス名を確認しやすくなります。

sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
sudo lsof -nP -iTCP:9090 -sTCP:LISTEN

Linuxではssを使って2つのポートをまとめて確認することもできます。一般ユーザーでプロセス情報が表示されない場合は、コアを何度も再起動するのではなく、権限を上げて再確認してください。

sudo ss -ltnp '( sport = :7890 or sport = :9090 )'

デスクトップクライアントとsystemdサービスで同じポートを二重に使用しない

Linuxでよくある競合は、mihomoをバックグラウンドサービスとして設定した後に、コア内蔵のデスクトップクライアントも起動するケースです。別々の設定を読み込んだ2つのプロセスが、どちらも7890で待ち受けようとします。デプロイ時に使ったサービス名がmihomo.serviceであれば、まず状態とログを確認してください。

systemctl status mihomo --no-pager
journalctl -u mihomo -n 50 --no-pager

デスクトップクライアントに切り替える場合は、sudo systemctl stop mihomoを実行してサービスを停止できます。自動起動を無効にするかどうかは、実際の運用に応じて判断してください。サービス名が異なる場合は、実際の名前を指定します。macOSでは、まずメニューバーから以前のクライアントを終了してください。コアがバックグラウンドの起動タスクから起動している場合は、設定時と同じ管理方法で停止します。そうしないと、プロセスを一度終了しても再び起動することがあります。

mixed-portを変更:設定とアプリ側のプロキシを両方更新

設定をバックアップし、最終的な設定ファイルの生成元を確認

GUIクライアントは、設定画面、オーバーライド、設定のマージ機能などを使って、コアが実行時に読み込むファイルを生成することがあります。キャッシュ内の購読YAMLを直接編集しても、購読の更新やクライアントの再起動で元に戻る場合があります。まず設定をバックアップし、使用中のクライアントが提供する永続設定の画面からポートを変更してください。メニュー名はクライアントごとに異なるため、特定の製品の操作手順をすべてのソフトに当てはめないでください。

  1. 変更先として使うポート(例:7891と9091)を確認し、すでに待ち受けに使われていないことを確かめます。
  2. 画面に「混合ポート」の項目がある場合は、7891に変更して保存します。手動でデプロイしている場合は、実際に読み込まれる設定ファイルを編集してください。
  3. クライアントの手順に従って設定を再読み込みするかコアを再起動し、ログで実際の待ち受けアドレスを確認します。
  4. システムプロキシ、ブラウザーのプロキシ拡張機能、コマンドラインの環境変数、手動設定したほかのプロキシアドレスも更新します。

以下は既存設定の最上位に追加するための例であり、単独でインポートできる完全な購読設定ではありません。既存のノード、プロキシグループ、ルールは残してください。同じ名前のキーがある場合は既存の値を変更し、重複して追加しないでください。新しいポートはあくまで例なので、使用前に空いていることを確認します。

config.yaml · ポート設定例
mixed-port: 7891
allow-lan: false
external-controller: 127.0.0.1:9091

port、socks-port、redir-port、tproxy-portも有効になっていないか確認してください。ログにエラーが出ている接続先だけを変更します。別々に待ち受ける必要がある複数の接続先に、同じアドレスとポートを設定しないでください。

システムプロキシとターミナルの環境変数を個別に確認

Windows 11では「設定」→「ネットワークとインターネット」→「プロキシ」→「プロキシ サーバーを使う」でアドレスとポートを確認できます。macOSでは「システム設定」→「ネットワーク」→現在のネットワークサービス→「詳細」→「プロキシ」を確認してください。クライアントがシステムプロキシを自動設定する場合は、通常、クライアント側で設定を適用し直すのが安全です。手動で設定した値は、あとから上書きされることがあります。

システムプロキシを変更しても、ターミナルの環境変数は自動更新されません。次の例では現在のターミナルセッションだけを変更し、新しいポートを確認できます。起動スクリプトや開発ツールの設定に7890が残っている場合は、別途変更してください。

PowerShell · 現在のセッション
$env:HTTP_PROXY = "http://127.0.0.1:7891"
$env:HTTPS_PROXY = "http://127.0.0.1:7891"
macOS / Linux · 現在のshell
export http_proxy=http://127.0.0.1:7891
export https_proxy=http://127.0.0.1:7891

HTTPS_PROXYはHTTPS宛ての通信に使うプロキシ設定を表しますが、ローカルのプロキシアドレスをhttps://で指定するという意味ではありません。ここではローカルのHTTPプロキシに接続するため、http://127.0.0.1:7891を使います。ALL_PROXYやアプリ独自のプロキシ設定も使っている場合は、あわせて確認してください。環境変数の大文字・小文字や優先順位の扱いは、ツールによって異なります。

9090を変更:コントロールパネルの接続先と認証設定も更新

競合しているのがexternal-controllerの場合、127.0.0.1:9091に変更したら、Webパネルのバックエンドアドレスもhttp://127.0.0.1:9091に変更してください。既存のsecretは維持し、パネルには対応する認証情報を入力します。デスクトップクライアントによってはコントロール用APIと認証情報を独自に管理します。画面とコアの設定に食い違いが生じないよう、まずクライアントの設定から変更してください。

  • プロキシは使えるが、パネルが接続できない:パネルが古い9090に接続していないか確認し、認証情報とクライアントのログも確認してください。
  • APIが401を返す:通常はHTTPサービスが応答しているものの、有効な認証情報がリクエストに含まれていないことを示します。ポートが使用中という意味ではありません。
  • 接続が拒否される:通常はその時点で、該当アドレスに接続を受け付けるプロセスがありません。コアが起動しているか、バインド先のアドレスが正しいか確認してください。

変更後の確認方法:待ち受け・プロキシ・コントロールAPIを個別にテスト

1. 変更先のポートを想定したプロセスが待ち受けているか確認

前述の確認コマンドを再度実行し、ポートを7891と9091に置き換えます。待ち受けがあるだけでなく、PIDが使用するコアのものかも確認してください。古いプロセスが残り、ブラウザーが古いポートを使っていると、問題が解消したように見えることがあります。

2. プロキシを明示して接続し、システムプロキシの残存設定を切り分け

WindowsのPowerShellでは、環境によってcurlが別のコマンドとして解釈される場合があるため、curl.exeを使います。macOSとLinuxではcurlを使ってください。次のコマンドは新しい接続先を明示します。--noproxy ""は、今回のリクエストでプロキシを迂回するホスト一覧を空にする指定です。接続確認に使う例であり、速度測定の基準ではありません。

curl.exe --noproxy "" --proxy http://127.0.0.1:7891 --connect-timeout 5 --max-time 15 -I https://example.com

接続先のサイトから応答があれば、ローカルのプロキシが少なくとも今回のリクエストを処理できたことがわかります。ただし、ルールにより最終的にDIRECTで接続される場合もあるため、コマンドが成功しただけでリモートノードが利用可能とは判断できません。クライアントの接続ログも確認し、対象ドメインに適用されたルール、プロキシグループ、実際の出口を調べてください。

3. コントロールAPIを個別に確認

curl.exe --connect-timeout 5 --max-time 10 -i http://127.0.0.1:9091/version

macOSとLinuxでは、コマンド内のcurl.exeをcurlに置き換えてください。認証が無効なら、正常なAPIはバージョン情報を返します。認証が有効な場合、認証情報を付けないと401が返ることがあります。テストのために既存のキーを削除しないでください。また、実際のキーが含まれるコマンド全体やログの画面を公開しないでください。

待ち受けプロセスがいないのにバインドできない場合:予約済みポートとエラーの種類を確認

ログにpermission denied、access permissions、cannot assign requested addressとある場合、通常のポート競合として扱わないでください。Windowsのポート除外範囲、存在しないローカルアドレスへのバインド、セキュリティソフトの制限など、原因によって対処が異なります。

Windowsでは次のコマンドでTCPの除外範囲を確認できます。対象ポートが範囲内にある場合は、範囲外の空きポートを選び、仮想化やネットワーク関連コンポーネントの設定を確認してください。システムが管理する除外設定を直接削除しないでください。

netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp

UDPの待ち受けでエラーが出ている場合、前述のTCPだけを確認するコマンドでは十分に調査できません。WindowsではGet-NetUDPEndpoint -LocalPort 7890、Linuxではsudo ss -lunp、macOSではsudo lsof -nP -iUDP:7890を実行してください。TCPとUDPは別々のポート空間を使うため、ログに記録されたプロトコルごとに確認します。

最後に、編集した設定ファイルが正しいか確認してください。サービスとして起動したmihomoは、起動オプションで別の設定ディレクトリを指定している場合があります。デスクトップクライアントが実行時に設定を生成することもあります。再起動後も古いポートで待ち受ける場合は、数字を次々と変更するのではなく、設定の読み込み元と上書きの順序を確認してください。

ポート競合の確認チェックリスト

  1. ログを確認:エラーが発生したアドレス、ポート、TCPまたはUDP、エラーの種類を記録します。
  2. プロセスを特定:netstat、lsof、ssで待ち受けPIDを調べ、実行ファイルのパスと起動方法を確認します。
  3. 対応を選択:不要な重複プロセスを停止するか、併用するサービスに別々のポートを設定します。
  4. 永続設定を変更:実際に有効なmixed-portまたはexternal-controllerを変更し、購読更新後に元の値へ戻らないようにします。
  5. 接続先も更新:プロキシ用ポートはシステムプロキシやアプリの設定に、コントロール用ポートはパネルのバックエンドアドレスと認証情報に反映します。
  6. 段階的に検証:待ち受けを確認してから、明示的なプロキシ接続、コントロールAPI、適用ルールの順にテストします。

TUNモードは仮想ネットワークアダプター経由で通信を処理する機能で、ローカルプロキシの待ち受けとは別の仕組みです。TUNを有効にしても、使用中の7890や9090が自動的に解放されることはありません。まずログで明確にエラーが出ている待ち受けを解決し、その後でTUNの権限、ルーティング、DNSを確認すると、複数の問題が絡み合うのを防げます。