まず障害が発生している層を切り分ける
Clash クライアントがサブスクリプションを更新するときは、通常、ドメイン名の解決、TCP と TLS 接続の確立、HTTP リクエストの送信、レスポンスの受信、サブスクリプション形式の判別、YAML またはノード URI の解析を順に行い、最後に mihomo などのコアへ結果を渡して読み込みます。画面に同じ「更新失敗」と表示されても、実際の問題箇所は異なる場合があります。更新を何度もクリックするだけでは、同じエラーを繰り返すことになります。
調査を始める前に、エラーの原文、発生時刻、クライアントが現在使用しているコアのバージョンを記録します。「使えない」とだけ残してはいけません。timeout、403 Forbidden、yaml: unmarshal errors、unexpected end of file などのキーワードがあれば、ネットワーク、アクセス制御、形式解析のどこに問題があるかを絞り込めます。
| 確認できる症状 | 優先して確認する項目 | よくある意味 |
|---|---|---|
| URLを貼り付けるとすぐ形式エラーになる | URLの完全性、レスポンス内容 | コピーが途中で切れている、またはAPIがWebページやJSONエラーを返している |
| 約10~30秒待つとタイムアウトする | DNS、ルーティング、TLS、端末のネットワーク | リクエストがサブスクリプションサーバーへ安定して到達していない |
| 更新成功と表示されるがノード数が0 | サブスクリプションの種類、プランの状態、内容形式 | レスポンスは読めるが、現在の入力先が必要とするデータではない |
| ブラウザでは開けるが、クライアントは403を返す | User-Agent、リクエストヘッダー、アクセス頻度 | サーバーがクライアントの特徴やリクエスト頻度で制限している |
| 古い設定は使えるが、新しいサブスクリプションを読み込めない | YAMLフィールド、プロキシプロトコル、コアのバージョン | 新しい内容に、現在のコアが対応していない構造が含まれている |
手順1:サブスクリプションURLが有効か確認する
コピー内容とHTTPステータスを確認する
まずURLをプレーンテキストエディターに貼り付け、先頭が https://、またはサービス提供元が明示した http:// で始まっていることを確認します。メッセージアプリでは、疑問符、等号、ハイフンの付近でURLが途中切れになることがあります。QRコードの読み取りで空白や改行が混入する場合もあります。URL末尾に token=、key= などのパラメータがある場合、1文字欠けただけでも401、403、または空の内容が返ることがあります。
端末ではレスポンスヘッダーだけを確認できます。Windows 11では「ターミナル」→「PowerShell」、macOSでは「アプリケーション」→「ユーティリティ」→「ターミナル」を開きます。以下のコマンドのアドレスはローカルで置き換え、実行結果を公開・転送しないでください。
curl -I -L --connect-timeout 10 --max-time 30 "サブスクリプションURL"
-L は301または302リダイレクトを追跡するオプションです。接続タイムアウトは10秒、全体の制限時間は30秒に設定されています。代表的なステータスコードは次のように判断できます。
- 200:サーバーは内容を返していますが、それが有効なサブスクリプションだとは限りません。
- 301、302、307、308:リダイレクトが発生しています。クライアントが古い、または転送先へ到達できない場合に失敗することがあります。
- 401、403:トークンの期限切れ、アカウント状態の異常、リクエスト特性の不一致、またはアクセス元の制限が考えられます。
- 404、410:APIのパスが変更された、または古いサブスクリプションURLが無効化されています。
- 429:短時間に更新しすぎています。再試行を止め、サーバー側の制限時間が終わるまで待ってください。
- 500、502、503、504:サブスクリプションサーバーまたは上流サービスに一時的な障害があります。時間を置いて再確認してください。
ブラウザで開けても、クライアントで更新できるとは限らない
ブラウザと Clash クライアントでは、DNS、プロキシ経路、Cookie、User-Agent、リダイレクトの処理方法が異なる場合があります。ブラウザにファイルが表示されても、そのブラウザ環境からアクセスできることしか分かりません。クライアントは、異なるリクエストヘッダー、プロキシループ、対象ドメインの解決失敗などが原因で失敗することがあります。
アカウント側の状態も確認してください。通信量の上限到達、プランの期限切れ、サブスクリプションURLの再発行後など、一部のサービスは明確な401を返さず、説明文やHTMLのログインページを返すことがあります。クライアントはその内容を受け取ると「解析失敗」と表示しがちです。見た目はYAMLエラーでも、実際にはサブスクリプション権限が変わっている可能性があります。
手順2:レスポンスがClashで認識できる形式か確認する
完全な設定、プロキシコレクション、汎用ノード一覧を見分ける
一般的なサブスクリプションには複数の構造があります。完全なClash設定は通常YAMLで、proxies、proxy-groups、rules、dns などのトップレベルフィールドを含みます。プロキシコレクションは通常 proxy-providers から参照され、内容の中心が payload になっている場合があります。別の汎用サブスクリプションはBase64でエンコードされたノードURI一覧で、デコードすると ss://、trojan://、vmess:// などの項目を確認できます。
これら3種類は用途が異なります。proxy-providers 専用のコレクションURLを完全な設定としてインポートすると、クライアントがプロキシグループやルールの不足を示すことがあります。逆に、ノード一覧だけを受け付ける変換入力欄へ完全なYAMLを入れると、ノード数が0になる場合があります。サービス提供元の表記が「Clash設定」「Mihomo設定」「プロキシコレクション」「汎用サブスクリプション」のどれなのかを先に確認してください。
最小限の完全な構成は、通常次のような形になります。実際の設定にはポート、DNS、その他のルールも含まれますが、インデントの関係は維持してください。
mixed-port: 7890
mode: rule
proxies:
- name: example-node
type: ss
server: 192.0.2.10
port: 443
cipher: aes-128-gcm
password: example-password
proxy-groups:
- name: PROXY
type: select
proxies:
- example-node
- DIRECT
rules:
- MATCH,PROXY
Webページ、エラーJSON、途中で切れたファイルを除外する
次のコマンドでレスポンス本文を保存し、テキストエディターで先頭数十行を確認します。ファイル名はローカルの一時名で構いません。
curl -L --connect-timeout 10 --max-time 30 \
-o subscription-response.txt \
"サブスクリプションURL"
先頭に <!doctype html>、<html>、ログインフォーム、認証コードの案内などがあれば、返っているのはWebページです。{"code":403,"message":"..."} のような構造なら、APIエラーのJSONです。ファイル末尾が閉じていない引用符やリスト、Base64文字列の途中で突然終わっている場合は、ダウンロードが中断されたか、サーバー側で内容が完全に生成されていない可能性があります。
- YAMLのインデントは階層を表します。リスト項目のハイフンは正しい階層に置いてください。
- Tab文字はYAMLのスキャンエラーを引き起こすことがあります。設定のインデントにはスペースを使用してください。
- ノード名に含まれるコロン、シャープ記号、波括弧などは、引用符で囲む必要がある場合があります。
- 同じ階層に重複したフィールドがあると、パーサーによって処理結果が異なることがあります。
- レスポンスヘッダーの Content-Type は手がかりになりますが、内容が有効かどうかを単独で判断することはできません。
手順3:User-Agentとリクエスト動作を比較する
一部のサブスクリプションAPIは、User-Agentに応じて異なる形式を返します。たとえばブラウザには案内ページ、ClashやmihomoにはYAMLを返す場合があります。また、User-Agentによって互換フィールドを選ぶAPIもあります。ブラウザでは200なのにクライアントが403やHTMLを受け取る場合は、YAMLを直接変更するのではなく、リクエスト特性を比較してください。
curlで一般的なmihomoのリクエスト識別子を再現できます。まずデフォルトのリクエストを試し、次に指定したUser-Agentで試します。ステータスコード、ファイルサイズ、本文形式に明確な差があれば、問題は通常サーバー側の識別ロジックにあります。
curl -L -A "clash.meta" \
--connect-timeout 10 \
--max-time 30 \
-o subscription-mihomo.yaml \
"サブスクリプションURL"
clash.meta を指定するとYAMLが返り、デフォルトのリクエストではWebページが返る場合は、クライアントにあるサブスクリプション用User-Agent設定を使うか、提供元に推奨値を確認してください。グラフィカルクライアントによってメニューの場所は異なりますが、「設定」→「サブスクリプション設定」または個別設定の「編集」→「リクエストヘッダー」にあることが一般的です。変更前に元の値を記録し、グローバルのリクエストヘッダーを他の設定へ誤って適用しないようにしてください。
アクセス頻度の制限とキャッシュも確認する
「更新」を連続してクリックすると、数十秒の間に複数のリクエストが送信されます。サーバーはトークン、IP、User-Agent単位で回数を数え、その後429、403、一時的な空レスポンスを返すことがあります。この場合は更新を止め、10~30分待ってから1回だけリクエストします。デスクトップ、スマートフォン、ルーターから同じURLを同時に繰り返し取得しないでください。
クライアントのキャッシュによって、「URLを直したのに古いエラーが出続ける」という錯覚が起きることもあります。まず設定一覧で設定名と変更内容を記録し、失敗したリモート設定を削除して再インポートします。動作中のローカル設定を直接上書きしないでください。設定ファイルの保存先を確認できるクライアントなら、キャッシュファイルの更新時刻とサイズも比較できます。更新時刻が変わっていなければダウンロード段階の失敗、時刻は変わっているのに有効化できなければ解析またはコア読み込みの問題に近いと判断できます。
手順4:mihomoコアと設定フィールドの互換性を確認する
サブスクリプションのダウンロードに成功しても、次にコアによる解析が行われます。Clash Premium、旧版Clash、Clash Meta、現在のmihomoでは、対応するプロトコルフィールドや機能の範囲が完全には一致しません。サブスクリプションサービスがテンプレートを更新すると、古いコアが認識できないプロキシ種別、トランスポートパラメータ、DNSフィールド、ルールプロバイダーの設定が追加されることがあります。そのため、同じURLが新しいクライアントでは使えても、長期間更新していないクライアントではエラーになる場合があります。
ログから具体的なフィールドを特定する
クライアントの「設定」→「ログ」を開き、レベルを一時的に info または debug にして、サブスクリプション更新または設定の切り替えを1回実行します。完了後は元のログレベルに戻してください。次の情報を重点的に探します。
- unsupported proxy type:現在のコアがサブスクリプション内のプロキシ種別に対応していません。
- field ... not found またはデシリアライズエラー:フィールド名、値の型、バージョン互換性に問題があります。
- proxy ... not found:プロキシグループが存在しないノードまたは別のプロキシグループを参照しています。
- rule provider ... error:メイン設定は読み込めていますが、外部ルールコレクションの取得または解析に失敗しています。
- bind: address already in use:設定の解析は成功している可能性があり、7890などのポートが別のプロセスに使用されています。
コアの互換性問題は、まずクライアント内蔵のコア更新機能で対処します。一般的な場所は「設定」→「コア」→「更新を確認」です。更新後はクライアントを完全に終了して再起動し、ログに表示される実際のコアバージョンが変わったことを確認してください。グラフィカルインターフェースだけ更新して古いコアを使い続けても、エラーは解消しません。
サブスクリプション解析とルールプロバイダーの失敗を切り分ける
完全な設定は、リモートの proxy-providers や rule-providers を引き続き参照することがあります。メインのサブスクリプションを取得できても、これらの子リソースにアクセスできるとは限りません。ノード一覧は存在するのに、設定の切り替え時にルールコレクションの失敗が表示される場合は、メインのサブスクリプションを再生成するのではなく、ログにある具体的なURL、HTTPステータス、キャッシュパスを確認してください。
たとえばメイン設定は直接接続で取得できても、ルールコレクションのURLにはプロキシが必要な場合があります。クライアント起動時にプロキシがまだ確立していないと、起動依存が発生することがあります。まず対象のリモートルールを一時的に無効化し、メイン設定が動作するかを確認してから、ルールコレクションの取得経路や更新方式を調整します。YAMLを変更した後は、先にインデントを確認し、クライアントの設定検証機能で読み込んでください。
手順5:ローカルネットワーク、DNS、プロキシループを確認する
まずシステムプロキシを無効にしてテストする
サブスクリプションの更新は通常クライアント自身が開始しますが、クライアントによっては直接接続、システムプロキシの利用、現在のプロキシポリシー経由のいずれかでアクセスします。現在のノードが無効で、サブスクリプションのドメインもそのノードへ送られていると、「ノードを復旧するにはサブスクリプション更新が必要なのに、更新には無効なノードが必要」というループになります。
- 現在の設定とプロキシグループの選択を記録する。
- 「設定」→「システムプロキシ」を無効にする。
- TUNモードを有効にしている場合は、「設定」→「TUNモード」も無効にする。
- 7890、7891、7892のいずれかのポートを使用している他のプロキシソフトを終了する。
- 直接接続のネットワークでサブスクリプションURLを再テストする。
- 更新が完了したら、システムプロキシとTUNを順に再有効化する。
システムプロキシとTUNを無効にするとすぐ復旧する場合、原因は通常、サブスクリプション形式ではなく、ルーティングルール、現在のポリシー、プロキシループにあります。サブスクリプションのドメインが誤ってプロキシポリシーへ送られていないか確認し、そのドメインに明示的な直接接続ルールを追加します。ルールは広範なプロキシルールより前に置いてください。
rules:
- DOMAIN,subscription.example.com,DIRECT
- MATCH,PROXY
上記のドメインは構造を示すための例です。実際の設定には、サブスクリプションサービスの本当のホスト名を入力してください。サブスクリプションが複数回リダイレクトされる場合は、最終転送先のドメインも確認します。入口のドメインだけを許可すると、2回目の転送で失敗することがあります。
DNS、システム時刻、TLSを確認する
端末で nslookup サブスクリプションのドメイン を実行し、アドレスが返ることを確認します。ブラウザは安全なDNSを使えても、システムの名前解決に失敗すると、クライアントはブラウザの解決結果を利用できないことがあります。一時的にスマートフォンのテザリングなど別のネットワークへ切り替えて再テストしてください。ネットワーク変更後に復旧するなら、現在のDNS、ルーターのフィルタリング、ネットワーク出口に問題がある可能性が高いです。
TLS証明書の検証には、正確なシステム時刻も必要です。端末の日付が1日ずれている、タイムゾーンが誤っている、長期間時刻が同期されていないと、certificate has expired、not yet valid などのエラーが発生します。Windows 11では「設定」→「時刻と言語」→「日付と時刻」→「今すぐ同期」、macOSでは「システム設定」→「一般」→「日付と時刻」で自動設定を有効にします。
ファイアウォールやセキュリティソフトが、ブラウザには影響を与えずクライアントのプロセスだけを制限することもあります。システムファイアウォールの許可リストを確認し、使用中の Clash クライアントと mihomo コアのプロセスが外向きの接続を確立できるようにしてください。テストのためにファイアウォールを長期間無効化するのは避け、ブロック履歴を確認して対象プログラムに範囲を限定した送信ルールを作成するのが適切です。
決まった順序で一通り確認する
複数の変数が同時に変わるのを避けるため、次の順序で実行します。各手順が終わるたびに1回だけテストし、ステータスコード、ファイルサイズ、ログの変化を記録してください。どの変更が効果を生んだのかを明確にできます。
- 状況を保存:エラー原文、発生時刻、クライアントバージョン、コアバージョン、現在のネットワークを記録する。
- URLを確認:リンクが途中で切れていないこと、アカウントが有効であること、トークンがリセットされていないことを確認する。
- HTTPを確認:接続タイムアウト10秒、全体の制限時間30秒でステータスコードとリダイレクトをテストする。
- 本文を確認:HTMLログインページ、JSONエラー、空ファイル、ダウンロードの途中切れを除外する。
- 種類を確認:完全なYAML、プロキシコレクション、汎用ノード一覧を区別する。
- リクエストヘッダーを比較:デフォルトのUser-Agentと clash.meta でレスポンスの違いを確認する。
- 互換性を確認:クライアントのコアを更新し、ログから未対応のフィールドやプロトコルを特定する。
- ネットワーク要因を分離:システムプロキシとTUNを一時的に無効にし、直接接続またはスマートフォンのテザリングでテストする。
- 再インポート:古い設定をバックアップしてから、失敗したキャッシュを削除し、リモート設定を再追加する。
- 結果を検証:ノード数、プロキシグループ、ルールコレクション、更新時刻が想定どおりか確認する。
| テスト結果 | 導き出せる結論 | 次の手順 |
|---|---|---|
| すべてのネットワークで401または403が返る | URLの権限またはサーバー側の制限が原因の可能性が高い | アカウント状態を確認し、サブスクリプションURLを再発行するか提供元へ問い合わせる |
| スマートフォンのテザリングでは使えるが、元のネットワークではタイムアウトする | 元のネットワークのDNS、ルーティング、または出口に問題がある | ルーター、システムDNS、ファイアウォールの記録を確認する |
| curlではYAMLが返るが、クライアントは失敗する | リクエストヘッダー、キャッシュ、またはコアの互換性が原因の可能性が高い | クライアントのログを確認し、コアを更新する |
| メイン設定は成功するが、ルールコレクションは失敗する | メインのサブスクリプション自体は有効 | rule-providersのURLとポリシーを個別に確認する |
| TUNを無効にすると更新に成功する | ルーティングループまたは起動依存が存在する | サブスクリプションのドメインルールと更新経路を調整する |
復旧後も設定が実際に使えるか検証する
サブスクリプション画面に「更新成功」と表示されるのは、最初の確認にすぎません。設定の更新時刻が新しくなっているか、ノード一覧が空でないか、プロキシグループの参照が正常かを確認し、遅延テストも実行してください。85 msや230 msのように具体的な数値が返れば、テストURLが対応するノード経由で接続を確立できています。タイムアウトが続く場合は、ノードまたはローカルネットワークを引き続き確認します。
続いて接続パネルを開き、通常のHTTPSページへアクセスします。新しい接続が発生したか、その接続がどのルールに一致し、どのプロキシグループとノードを使ったかを確認してください。ルールモードではサブスクリプションサイトを直接接続し、その他の宛先をルールで振り分けます。グローバルモードでは、ほとんどの通信が現在のグローバルポリシーへ渡されます。検証時は、現在のモードが想定どおりであることを確認してください。
システムプロキシにデフォルトの混合ポート 7890 を使っている場合は、OSのプロキシアドレスが 127.0.0.1:7890 になっているか、ログにポート占有エラーがないかも確認します。TUNを使う場合は、TUNの状態、デフォルトルート、DNSが復旧しているかを確認してください。ブラウザのキャッシュページだけで接続成功と判断しないでください。
安定したら、リモート設定の自動更新間隔を適切な値に設定します。たとえば6時間、12時間、24時間です。分単位のポーリングは通常必要なく、サーバー側の頻度制限を招くおそれもあります。クライアントのアップグレード、コアの切り替え、サブスクリプションテンプレートの変更後に、手動更新と設定チェックを1回行えば十分です。