まず、リッスンに失敗しているポートを確認

Clashクライアントの起動時にaddress already in useが表示される場合、通常はカーネルがリッスンしようとしているローカルアドレスとポートがすでに使用されています。これは端末上にプロキシの入口を作成する段階で起きる問題です。サブスクリプションの無効や、リモートノードの障害を意味するものではありません。この場合、サブスクリプションを何度も更新したり、ノードを切り替えたりしても、ローカルのポート競合は解消しないのが一般的です。

まずクライアントのログ画面を開き、listen、bind、in useのいずれかを含むエラー行全体を探します。アドレス、ポート、プロトコルを控えてください。以下はエラー形式の例で、実際の端末で確認した結果ではありません。

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

ここで確認するのは、ローカルのTCP 7890です。ログに127.0.0.1:9090と表示されている場合は、外部コントロールインターフェースを調べます。プロキシポートをそのまま変更しないでください。0.0.0.0:7890は、すべてのIPv4インターフェースでリッスンすることを示します。同じポートを使う特定アドレスでのリッスンと競合する場合があります。[::]:7890の場合は、システムのIPv6デュアルスタック動作も考慮して判断してください。

設定項目 用途 変更後に合わせて更新する設定
mixed-port HTTPとSOCKSのプロキシを同じポートで提供 システムプロキシ、ブラウザのプロキシ、コマンドラインのプロキシ環境変数
port HTTPプロキシ専用の入口 その入口を使うHTTPプロキシ設定
socks-port SOCKSプロキシ専用の入口 アプリ内のSOCKSプロキシ設定
external-controller クライアントやパネルからアクセスするコントロールAPI クライアントやパネルのコントロールインターフェース接続設定

Windows:netstatでポートを使用中のプロセスを特定

ローカルアドレス、リッスン状態、PIDを確認

Windowsターミナルまたはコマンドプロンプトを開き、次のコマンドを実行します。接続情報の確認は通常、一般ユーザー権限で行えます。プロセス情報の一部を取得したり、サービスを操作したりするには、管理者権限が必要な場合があります。

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

出力される列は、左からプロトコル、ローカルアドレス、外部アドレス、状態、PIDです。必ずローカルアドレスの列を確認し、ポートが実際に7890であることを確かめてください。文字列による絞り込みでは、外部アドレスや7890より長いポート番号まで一致する場合があります。TCPプロキシの入口を確認するときは、行に7890が含まれているだけで処理を終了せず、状態がLISTENINGの行を確認します。

PowerShellでポート番号を正確に指定して絞り込むと、目視での確認を減らせます。

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

検索結果のPIDが4321だった場合、次のコマンドでプログラム名を確認します。4321はコマンドの形式を示す例です。実際の操作では、確認したPIDに置き換えてください。

tasklist /FI "PID eq 4321"

プロセスの詳細を確認してから、終了するか判断

  • 別のプロキシクライアント:トレイメニューから正常に終了し、もう一度ポートを確認してください。ウィンドウを閉じただけでは、バックグラウンドで動作し続けることがあります。
  • 現在のクライアントの古いカーネル:まずクライアントを終了し、タスクマネージャーで残ったプロセスのパスとコマンドラインを確認します。カーネルの残留プロセスだと確認できてから終了してください。
  • サービスとして起動したカーネル:ウィンドウを閉じてもサービスが動作し続けることがあります。終了後すぐに再起動されないよう、クライアントのサービス管理機能から該当するサービスを停止してください。
  • 引き続き使う必要がある別のプログラム:そのプログラムは終了せず、Clashに別の空きポートを割り当ててください。ポートを空けるために、システムサービスをむやみに停止しないでください。

タスクマネージャーの「詳細」タブでPIDを確認できます。列の見出しを右クリックして「列の選択」を開くと、コマンドラインを表示できます。使用中のポートがシステムプロセスのものなら、ポート番号だけを根拠に強制終了してはいけません。関連サービスを特定するか、別のポートを使ってください。

macOS・Linux:lsofまたはssでリッスン中のプロセスを確認

macOSでは「ターミナル」を開き、次のコマンドを実行します。-nPはアドレスとポートを数値で表示し、-sTCP:LISTENはTCPのリッスンソケットに結果を絞り込みます。

lsof -nP -iTCP:7890 -sTCP:LISTEN

COMMAND、PID、NAMEを確認します。ほかのユーザーのプロセスがリッスンしている可能性があり、通常の検索では情報がすべて表示されない場合は、必要な権限があることを確認したうえでsudoを付けて再実行してください。Linuxでlsofがインストールされていない場合は、通常iproute2に含まれるssを使えます。

sudo ss -ltnp 'sport = :7890'

プロセスの起動コマンドをさらに確認するには、実際のPIDを指定して検索します。

ps -p 4321 -o pid,ppid,command

アプリのメニューやサービス管理機能から、使用中のプロセスを正常に停止してください。管理画面を失ったプロセスの残留だと確認できた場合は、kill -TERM 4321のように通常の終了シグナルを送信できます。最初から強制終了するのは避けてください。プロセスが繰り返し起動する理由が分からないまま、正常な終了処理を飛ばすことにもなりかねません。

mixed-portを変更する前に、有効な設定レイヤーを確認

7890を別の必要なプログラムが使用中だと確認できたら、7892に変更できます。ただし、先に前述のコマンドで7892が空いていることを確認してください。番号を変えるだけでは、新しいリッスン先が選ばれるだけです。ブラウザ、ターミナル、コントロールパネルの接続設定は自動で変更されません。

Clash Meta(mihomo)系カーネルの部分的な設定例です。ノードやルールを含む完全な設定ファイルではありません。既存の設定に統合し、サブスクリプション、プロキシグループ、ルール、アクセス認証の設定は維持してください。

mixed-port: 7892
allow-lan: false
external-controller: 127.0.0.1:9090

この例ではmixed-portを7892に変更し、コントロールインターフェースの9090は維持します。ログでコントロールポートの競合が確認されていない場合、同時に変更する必要はありません。allow-lan: falseはLANからのアクセスを制限します。個人用端末でローカルアクセスだけを使う場合、ポート競合への対処としてリッスン範囲をネットワーク全体に広げないでください。

GUIクライアントのポート設定がサブスクリプションのファイルを上書きする場合

  1. 現在のプロキシポート、コントロールポート、使用中の設定名を記録し、復元できる設定ファイルを保存します。
  2. クライアントの設定に「Mixed Port」「プロキシポート」「カーネル設定」などの項目がないか確認します。メニューの構成はクライアントによって異なるため、全体のリッスン設定を管理する機能から変更してください。
  3. クライアントが設定の上書きやマージに対応している場合は、ローカルのリッスン設定を、そのクライアントが実際に対応する永続化レイヤーに追加します。すべてのサブスクリプションファイルで同じ上書き方法が使えるとは限りません。
  4. 変更を適用し、カーネルを再読み込みまたは再起動してからログを確認します。ポートのリッスン設定を反映するために再起動が必要かどうかは、クライアントとカーネルの動作によって異なります。

ダウンロードしたサブスクリプションのYAMLを直接編集しても、次回の更新時に上書きされる可能性があります。逆に、クライアントが起動時に画面上の設定で同じ項目を上書きするため、サブスクリプションのファイルを編集しても反映されないことがあります。実際に有効な設定、カーネルログ、システムのリッスン状況を確認してください。エディターで保存した行だけでは判断できません。

独立したportやsocks-portも有効になっていないか確認してください。これらをmixed-portと同じリッスンアドレス・ポートに設定しないでください。また、YAMLのトップレベルにmixed-portを重複して記述しないでください。重複キーは解析エラーや、どちらの設定が適用されるか不明確になる原因になります。

コントロールポートの競合:external-controllerを個別に変更

プロキシの入口7890は正常にリッスンしているのに、9090でエラーが発生する場合は、コントロールAPIに問題があります。接続情報をGUIで読み込めない、プロキシグループを切り替えられない、パネルにカーネルの切断が表示される、といった症状が起こることがあります。クライアントによっては、これを起動失敗として報告する場合もあります。まず9090を使用中のプロセスを確認し、必要であれば空いている9091に変更してください。

external-controller: 127.0.0.1:9091

変更後、外部パネルからは新しいコントロールアドレスに接続する必要があります。GUIクライアントがコントロールインターフェースを管理している場合は、対応する設定も変更し、画面とカーネルの接続先を一致させてください。カーネルの設定ファイルだけを編集し、GUI側の接続先を変更しないと、プロキシは使えても画面から接続できないことがあります。既存のsecret認証は維持し、インターフェースにアクセスする必要があるパネルにも共有してください。トラブル対処のために認証を無効にしないでください。

競合を解消するために、コントロールインターフェースを0.0.0.0:9091に変更しないでください。インターフェースの公開範囲が広がるうえ、既存のリッスンとの競合を避けられる保証もありません。コントロールインターフェースとmixed-portは別々の設定です。競合している箇所だけを変更すれば、動作確認や切り戻しが容易になります。

システムプロキシとアプリの設定を更新し、古いポートへの接続を防ぐ

mixed-portを7892に変更しても、127.0.0.1:7890を参照しているアプリは引き続き失敗します。GUIクライアントは、システムプロキシを有効にすると新しい値を設定することがありますが、自動更新されるかどうかはクライアントの仕様によります。新しいポートを適用したら、システムプロキシを一度オフにしてから再度オンにし、実際に設定されているアドレスを確認してください。

  • Windows 11:「設定」→「ネットワークとインターネット」→「プロキシ」→「手動プロキシ セットアップ」→「プロキシ サーバーを使う」の「編集」を開き、アドレスとポートを確認します。自動構成スクリプトを使っている場合は、スクリプトが指定するプロキシアドレスも確認してください。
  • macOS 13以降:「システム設定」→「ネットワーク」→現在の接続→「詳細」→「プロキシ」を開き、「Webプロキシ(HTTP)」「セキュアWebプロキシ(HTTPS)」「SOCKSプロキシ」のうち、実際に有効になっている項目を確認します。
  • Firefox:「設定」→「一般」→「ネットワーク設定」→「接続設定」を確認してください。Firefoxに個別の手動プロキシを設定している場合、OSのプロキシ設定を変えても自動では同期されません。
  • ターミナルと開発ツール:HTTP_PROXY、HTTPS_PROXY、ALL_PROXYのほか、Git、エディター、コンテナに個別設定したプロキシアドレスを確認してください。

mixed-portはHTTPとSOCKSのリクエストを受け付けますが、アプリ側では適切なプロトコルを選ぶ必要があります。HTTPプロキシのアドレスはhttp://127.0.0.1:7892のように指定できます。SOCKSプロキシ経由で名前解決を行う場合は、対応するツールでsocks5h://127.0.0.1:7892を使用できます。HTTPSサイトへの接続にHTTPプロキシのトンネルを使う場合も、ローカルプロキシのアドレスをhttps://で指定する必要はありません。

TUNモードは仮想ネットワークインターフェースで通信を取り込む仕組みで、システムのHTTPプロキシと同じものではありません。TUN環境でブラウザが使えても、古い7890の設定が直ったとは限りません。一方、通常のmixed-portの競合を解消するためにTUNデバイスをアンインストールする必要もありません。接続先の混同を避けるため、プロキシの入口を確認するときは新しいポートを明示してください。

修正結果と再起動後の設定維持を確認

まずリッスンを確認し、実際のリクエストでもテスト

7892を再度確認し、想定したカーネルプロセスがリッスンしていることと、ログにバインド失敗が残っていないことを確かめます。続いてcurlで新しい入口に明示的に接続します。Windows PowerShellではcurl.exeを使うと、環境によって同名コマンドのエイリアスが影響するのを避けられます。

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

macOSやLinuxでは同じ引数を使い、コマンド名をcurlにします。ここでの5秒と15秒は、それぞれ接続時とリクエスト全体のタイムアウト上限です。通信速度の測定値ではありません。この例ではローカルプロキシの認証は無効になっています。認証を設定している場合は既存の方法で認証情報を渡し、公開ログにパスワードを貼り付けないでください。

  • ローカル接続が拒否される:新しいポートでリッスンしているか、アドレスが一致しているか、カーネルが終了していないかを確認してください。
  • リクエストがカーネルに届くが、外部接続がタイムアウトする:接続ログを確認し、ルールの適用結果、ノード、DNSを調べてください。ポートのリッスンが復旧しても、その先の通信が正常とは限りません。
  • curlは成功するがブラウザでは失敗する:ブラウザ独自のプロキシ設定、拡張機能、自動構成スクリプト、古い接続を確認してください。すぐにポートを再変更する必要はありません。
  • ブラウザは使えるがパネルは失敗する:コントロールインターフェースのアドレスと認証を確認してください。コントロールインターフェースのエラーをプロキシ入口の障害と混同しないでください。

クライアントを終了して再起動し、もう一度確認

テストが終わったらクライアントを正常に終了して再起動し、引き続き7892でリッスンしていることを確認します。起動直後に問題が起きる場合は、ログイン時の起動項目とサービスモードも確認してください。必要な自動起動だけを有効にし、旧クライアントと新クライアントが同じポートを取り合わないようにします。

TCPの検索結果にリッスン中のプロセスがないのにバインドできない場合は、まずログの時刻、アドレス、プロトコルをもう一度確認してください。Windowsではaddress already in useとaccess permissionsで調べるべき内容が異なります。後者は予約済みポートやセキュリティポリシーが関係する場合があります。次のコマンドでTCPの除外ポート範囲を確認できますが、システムの予約項目を削除しないでください。

netsh interface ipv4 show excludedportrange protocol=tcp

最終的に、次の4点をすべて満たしていることを確認します。カーネルが指定したポートで正常にリッスンしていること、システムとアプリの接続先が新しい入口になっていること、コントロール画面から接続できること、再起動後も設定が維持されることです。元に戻す場合は、先に元のポートが空いていることを確認してから設定を復元し、システムプロキシも更新してください。クライアントを一時的に終了する場合も、クライアントが設定したシステムプロキシを無効にし、停止したローカルポートに通信を送り続けないようにしてください。