まずエラーに表示されたアドレスを確認し、プロセスを終了するかポートを変更するか判断します

次の順に対処します:バインドに失敗したポートを確認 → 使用中のプロセスを特定 → 重複して起動したインスタンスを終了するか、空いているポートに変更 → システムプロキシを更新。サブスクリプションを削除したり、何度も再インストールしたりする必要はありません。ポート競合はローカルでの待ち受け時に発生するため、通常はリモートのプロキシノードが使えるかどうかとは関係ありません。

Clash系クライアントでは、設定を管理するGUIとは別に、ClashやClash Meta(mihomo)のコア、またはクライアントが起動したバックグラウンドサービスがポートを待ち受けている場合があります。ウィンドウを閉じてもコアが終了するとは限りません。タスクトレイ、スタートアップ項目、サービスモードによって待ち受けが続くことがあります。

ログから確認する3つの情報

listen tcp 127.0.0.1:7890: bind: address already in use

これはログの例であり、実機で取得した結果ではありません。失敗したのはTCPの待ち受けで、アドレスは 127.0.0.1、ポートは 7890 です。Windowsでは「通常、各ソケット アドレスは 1 回だけ使用できます」というメッセージが表示されることもあります。実際のポート番号を控え、以降のコマンドではログに表示された番号を指定してください。

設定項目用途確認ポイント
mixed-portHTTPとSOCKSの接続を同じポートで受け付ける7890や7897はよく使われる設定値ですが、標準で決まった番号ではありません
port / socks-portHTTPとSOCKSの個別ポートmixed-portと重複していないか確認
external-controllerコアのコントロールAPI9090はよく使われる例で、インターネット接続用のプロキシポートではありません
dns.listenコアのDNS待ち受けアドレスUDPとTCPの両方が関係する場合があるため、TCPだけで判断しない

Windows:待ち受けポートからPIDと実行ファイルのパスを調べる

PowerShellを開き、まずPC上のTCP待ち受けを確認します。以下では7890と7897を例にします。通常の権限で待ち受け一覧を確認できますが、ほかのユーザーのプロセスパスを調べるには、管理者としてターミナルを開く必要がある場合があります。

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

OwningProcess に表示されるのがプロセスのPIDです。例としてPIDが6420と表示された場合は、続けてプロセス名と実行ファイルのパスを調べます。6420は説明用の値です。実際の操作では検索結果を使い、この番号のプロセスをそのまま終了しないでください。

Get-Process -Id 6420 | Select-Object Id,ProcessName,Path
Get-CimInstance Win32_Process -Filter "ProcessId = 6420" |
  Select-Object ProcessId,ParentProcessId,ExecutablePath,CommandLine

コマンドプロンプトでも確認できます

netstat -ano -p tcp | findstr ":7890"
netstat -ano -p tcp | findstr ":7897"
tasklist /FI "PID eq 6420"

netstat の出力にはローカルアドレスとリモートアドレスの両方が含まれます。絞り込みコマンドは候補を減らすだけなので、ローカルアドレスのポートが実際に7890で、状態が LISTENING であることを確認してください。リモートアドレスに7890が含まれている場合や、状態が TIME_WAIT の場合は、ローカルの待ち受けポートを使用中のプロセスがある証拠にはなりません。

  • パスが別のClashクライアントを示している場合は、タスクトレイのメニューから正常に終了し、ポートを再確認します。
  • パスが現在使用中のクライアントのコアを示している場合は、正常に動作中か、別のインスタンスが起動している可能性があります。ログの時刻や親プロセスも確認してください。
  • パスが別のアプリを示している場合は、Clash側のポート変更を優先してください。ポートを空けるために無関係なプログラムを終了しないでください。
  • PIDがすぐに変わる場合は、サービスモード、タスクマネージャーの「スタートアップ アプリ」、サービス管理ツールを確認します。バックグラウンドのコンポーネントが自動的に再起動している可能性があります。

画面から操作できなくなった残存コアだと確認できた場合に限り、Stop-Process -Id 6420 の実行を検討してください。プロセスを終了すると、既存の接続も切断されます。サービスの場合は、サービス管理ツールによる再起動を防ぐため、先にクライアント側からサービスを停止してください。Clashを含む名前のプロセスをまとめて終了するのは避けましょう。

macOSとLinux:待ち受けアドレスとバックグラウンドサービスを確認する

macOS:lsofを使う

sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
sudo lsof -nP -iTCP:7897 -sTCP:LISTEN
ps -p 6420 -o pid,ppid,command

-nP を指定するとアドレスとポートが数値で表示され、ログと直接照合できます。lsof にはコマンド名、PID、待ち受けアドレスが表示されます。まずメニューバーから古いクライアントを終了し、もう一度確認してください。バックグラウンドサービスが待ち受けを開始している場合、メインウィンドウを閉じただけではコアが残ることがあります。該当クライアントのサービス設定から停止してください。

Linux:ssを使う

sudo ss -ltnp 'sport = :7890'
sudo ss -ltnp 'sport = :7897'
ps -p 6420 -o pid,ppid,args

-l は待ち受けのみ、-t はTCP、-n は数値表示、-p は関連プロセスを表示します。systemdで管理されているプロセスは、実際のサービスユニットを確認してから停止してください。サービス名を推測してはいけません。クライアントによってユーザーサービスとシステムサービスのどちらを使うか異なるため、それぞれのサービス一覧で確認します。

通常の残存プロセスであれば、まず kill -TERM 6420 で終了を要求し、ポートが解放されたか再確認します。いきなり強制終了せず、正常に終了する時間を与えてください。終了後にPIDが変わってもポートが使用中なら、繰り返しプロセスを終了するのではなく、自動起動の原因を調べます。

mixed-portを変更する:新しいポートを確認してから設定を保存する

使用中のプロセスを止められない場合は、Clashのmixed-portを空いている番号に変更します。たとえば17890を使うなら、先ほどの確認コマンドで指定したポートを17890に置き換えてください。待ち受けが表示されなくても、その時点で該当プロセスが見つからなかったというだけです。再起動後のバインド結果も確認しましょう。

  1. 使用中のクライアントで「混合端口」または「Mixed Port」の設定を探し、現在の値を控えます。メニュー名はクライアントのバージョンによって異なります。コアのコントロールポートをmixed-portと取り違えないようにしてください。
  2. mixed-portを 17890 に変更して保存し、クライアントの案内に従ってコアを再読み込みまたは再起動します。
  3. 実行ログを確認し、該当ポートのバインド失敗が再発していないことを確認します。
  4. 待ち受け一覧を再確認し、17890のPIDが現在使用中のクライアントのコアと一致することを確認します。

YAMLを直接編集する場合は、必要な項目だけ変更する

mixed-port: 17890
allow-lan: false

これはトップレベル設定の一部であり、サブスクリプション全体ではありません。既存のプロキシ、グループ、ルールを残したまま、既存設定に反映してください。allow-lan: false は、この例ではLANからのアクセスを許可しない設定です。既存の設定に別の用途がある場合は、ファイル全体を上書きせず、実際の要件に合わせて維持してください。

同じ設定内の port、socks-port、external-controller など、ほかの待ち受け項目も確認し、別々の待ち受けが同じアドレスとポートを使わないようにします。同名の mixed-port を追加しないでください。キーが重複した場合の処理は、パーサーによって異なることがあります。

サブスクリプションの更新でファイルが上書きされたり、一時的に生成された実行用設定が再起動時に作り直されたりする場合があります。クライアントの永続設定か、対応している上書き機能を使ってください。複数箇所でポートを設定している場合は、最終的に適用される設定とログを確認し、実際に17890で動作していることを確かめます。上書きの適用順はクライアントによって異なるため、エディターに表示された1行だけでは判断できません。

各項目の用途はmixed-portの設定方法、YAMLのインデントはYAML設定の基本をご覧ください。これらのローカル待ち受け設定を変更するために、プロキシノードのサーバーポートを変更する必要はありません。

システムプロキシを更新する:ポート変更後は接続先も更新する

コアを17890に変更しても、システムプロキシが7890のままではブラウザーは接続できません。クライアントがシステムプロキシを設定する場合は、いったん「システムプロキシ」をオフにしてから再度オンにし、接続先を更新します。その後、システム設定を開いて値を確認してください。スイッチの状態だけで判断しないようにしましょう。

  • Windows 11:「設定」→「ネットワークとインターネット」→「プロキシ」→「プロキシ サーバーを使う」→「編集」の順に開きます。アドレスが 127.0.0.1、ポートが 17890 になっていることを確認してください。Windows 10では、通常「プロキシ サーバーを使う」スイッチから設定します。
  • macOS 13以降:「システム設定」→「ネットワーク」→現在のネットワークサービス→「詳細」→「プロキシ」の順に開きます。有効になっているWebプロキシ、安全なWebプロキシ、SOCKSプロキシを確認してください。mixed-portを使う場合は、必要な接続方式のポートを同じローカルポートに設定できます。
  • Linuxデスクトップ:デスクトップ環境のネットワークプロキシ設定で、手動プロキシを確認します。GNOMEとKDEではメニューの場所が異なるため、すべてのディストリビューションで同じ場所にあるとは限りません。

ブラウザー拡張機能、ダウンロードツール、IDE、ターミナルは、システムプロキシに従わず個別の接続先を使うことがあります。手動設定した7890や7897を17890に変更してください。ターミナルの環境変数を変更しても、すでに開いているターミナルや起動済みのプログラムには古い値が残る場合があるため、開き直す必要があります。

# 現在のshellでプロキシ環境変数を確認する。出力はshellによって異なる
env | grep -i proxy

# PowerShellでプロキシ環境変数を確認する
Get-ChildItem Env: | Where-Object Name -Match 'proxy'

これらのコマンドは値を確認するだけで、環境変数は変更しません。HTTP_PROXY、HTTPS_PROXY、ALL_PROXY、NO_PROXY を確認してください。通常のHTTP mixed-port経由でHTTPSサイトに接続する場合、HTTPS_PROXY も http://127.0.0.1:17890 と記述するのが一般的です。変数名は対象のリクエスト種別を示すもので、ローカルプロキシにTLSが必要という意味ではありません。

修正を確認する:待ち受け、プロキシ接続先、実際のリクエストをそれぞれ確認する

修正後は、プロキシのアドレスを明示したリクエストを1回実行して確認します。システムプロキシのキャッシュやブラウザー拡張機能の影響を避けるためです。以下ではテスト用に予約されたドメインを使用します。通信速度を測定するものではなく、すべてのWebサイトにアクセスできることを示すものでもありません。

# Windows PowerShell:旧バージョンのエイリアスを避けるためcurl.exeを明示して実行する
curl.exe --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 -I https://example.com

# macOS / Linux
curl --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 -I https://example.com

127.0.0.1:17890 に接続できない場合は、まずコアがポートを待ち受けているか確認します。ローカルプロキシに接続できても、接続先へのタイムアウト、DNSエラー、TLSエラーが発生する場合は、ローカルポートの問題は解消している可能性があります。ルールの適用結果、接続先の名前解決、選択中のプロキシを引き続き確認してください。HTTPヘッダーやトンネル応答は調査の手がかりにすぎません。どのステータスコードでも接続全体が正常だと判断しないでください。

使用中のプロセスが見つからない場合の追加確認

  • ログ上の失敗対象がUDPの場合:Windowsでは Get-NetUDPEndpoint -LocalPort 7890、Linuxでは sudo ss -lunp 'sport = :7890'、macOSでは sudo lsof -nP -iUDP:7890 を実行します。7890は実際にエラーが出たポート番号に置き換えてください。
  • Windowsでアクセス権限エラーが出る場合は、netsh interface ipv4 show excludedportrange protocol=tcp を実行して除外ポート範囲を確認します。IPv6が関係する場合は、IPv6の範囲も確認してください。範囲外の空いているポートに変更し、システムの予約項目を直接削除しないでください。
  • ポートを解放したのにエラーが続く場合は、ログの時刻が画面に残っている過去の記録ではなく、今回の起動時のものか確認し、自動再起動するサービスがないか調べてください。
  • ポートを変更しても再起動後に元の値へ戻る場合は、サブスクリプションの更新、上書き設定の優先順位、クライアントの永続設定を確認し、設定を書き戻している箇所を特定してください。

後から確認できるよう、最後に記録を残す

元のポート、新しいポート、使用中だったプログラムのパス、変更した設定箇所を記録してください。次回起動時は、想定したクライアントだけが17890を待ち受けていることと、システムプロキシやアプリのプロキシが同じ接続先を指定していることを確認します。クライアントを使わなくなるときは、終了前にシステムプロキシをオフにしてください。停止したローカルポートへの接続が続くのを防げます。