v2rayNGの接続ボタンを押すとすぐ停止する、またはログにエラーが続けて表示されるAndroidユーザー向けです。まず、設定の読み込み・ローカル待ち受け・リモート接続のどの段階で問題が起きているかを確認し、エラーをたどって該当する項目を特定します。ログの取得手順、よくあるエラーとの照合方法、設定例を紹介します。変更は一度に1か所にとどめ、原因を特定できていた問題を複雑にしないようにしましょう。
まず確認:コアが起動しないのか、起動後に接続できないのか
v2rayNGはAndroid向けクライアントです。この記事では、使用しているXrayコアのログをもとにトラブルを調べます。接続後にVPNアイコンが表示されても、Android側でサービスが開始したことを示すだけで、ノードが使えるとは限りません。一方、Webページが開けなくても、コアの起動失敗とは限りません。ローカルの待ち受けが確立し、初回アクセス時にタイムアウトする場合は、リモート接続経路を確認しましょう。
| 問題が起きた段階 | ログの手がかり | 優先して確認する項目 |
|---|---|---|
| 設定の読み込み | failed to read config files、invalid character | JSON構文、設定の読み込み元 |
| 設定の構築 | failed to buildに続く具体的なフィールドの原因 | プロトコル名、フィールドの型、コアの対応状況 |
| ローカル待ち受けの開始 | bind: address already in use | 待ち受けアドレスとローカルポート |
| リモートへのリクエスト | i/o timeout、connection refused | サーバーアドレス、リモートポート、接続経路 |
| セキュリティまたは通信のハンドシェイク | x509:、bad handshake | 証明書のドメイン、TLS、通信設定 |
1つのログに>で複数段階の原因がつながって表示されることがあります。先頭の「起動失敗」は結果であり、その後に続く文字・ポート・証明書についての説明が根本原因に近い情報です。ログを読むときはエラーの流れ全体を残し、末尾から具体的な対象を探してください。目立つ赤い1行だけを切り取らないようにしましょう。
ログを一度きれいに取得する:接続ボタンを押すところから
現在のノードとカスタム設定を保存してから、ログを取得します。v2rayNGはバージョンによって翻訳やメニューの場所が異なる場合があります。一般的には、メイン画面左上のメニューに「ログ」があり、ログレベルは「設定」で変更できます。同じ名前の項目が見つからない場合は、使用中のバージョンの画面を確認してください。デスクトップ版v2rayNの「パラメーター設定」の手順を流用しないでください。
-
環境を記録する
Androidの「設定」→「アプリ」→「v2rayNG」のアプリ情報でクライアントのバージョンを確認し、Androidのバージョン、ノードのプロトコル、カスタム設定の使用有無も記録します。ログにコアのバージョンが表示されている場合は、それも控えてください。
-
接続を停止する
v2rayNGのメイン画面に戻り、接続ボタンを押してサービスを停止します。AndroidのVPNサービス切り替えによる影響を避けるため、ほかのVPNアプリも一時的に停止してください。
-
ログレベルを変更する
「設定」→「ログレベル」を開き、まず
infoを選択します。手がかりが足りない場合は、一時的にdebugへ変更してください。完全なカスタムJSONを使っている場合は、log.loglevelも確認します。 -
問題を再現する
「ログ」を開いてログを消去し、メイン画面に戻って一度だけ接続します。サービスが動作し続ける場合は、Webページに一度アクセスしてからログに戻り、同じ時間帯の記録を確認してください。
-
前後の記録を残す
最初の失敗の前後を含め、ログ全体をコピーします。共有する前に、サブスクリプションURL、UUID、パスワード、サーバー情報を伏せてください。ただし、フィールド名、エラーの順序、同じアドレス同士の対応関係は残します。
debugは詳細な情報、infoは通常の処理、warningは注意が必要な状態、errorは処理の失敗を示します。ノードの良し悪しを評価するものではありません。特定のリクエストでエラーが出ても、コア全体が終了したとは限りません。エラーが記録されない場合も、ログレベルが高すぎる可能性があります。調査が終わったら、詳細なログレベルを元に戻し、不要な記録を減らしてください。
JSON構文エラー:まず形式を直し、その後ノードを確認
カスタム設定を読み込んだ直後に起動できない場合は、まず解析エラーを確認します。JSONのキー名と文字列には半角の二重引用符が必要です。全角引用符、カンマの抜け、末尾の余分なカンマはエラーの原因になります。設定の移行やトラブル調査をしやすくするため、ここではコメント機能の拡張に依存しない厳密なJSONを例に使います。
エラー:invalid character '}' looking for beginning of object key string
原因:オブジェクトの最後の項目の後にカンマが残っています。解析側は次のキー名を待っているところで、閉じ波括弧に遭遇しています。
対処法:エラー位置の直前にある項目を確認し、末尾のカンマを削除します。隣接するオブジェクトも確認し、閉じ波括弧をそのまま削除しないでください。
エラー:unexpected end of JSON input
原因:設定の途中で内容が終わっています。コピー漏れ、閉じ括弧の不足、閉じ引用符の欠落などがよくある原因です。
対処法:元の設定からもう一度読み込み、末尾の引用符、角括弧、波括弧がそれぞれ対応しているか確認します。勘で括弧を次々に追加しないでください。
次の部分例では、"warning"の後に余分なカンマがあります。エラー位置はカンマではなく次の行の閉じ波括弧を示すことがあるため、特定するときは1行前も確認してください。
{
"log": {
"loglevel": "warning",
}
}
修正後の例は次のとおりです。logの書き方を示すだけで、単独で接続できる完全な設定ではありません。元のファイルで該当するオブジェクトだけを置き換え、既存のinbound、outbound、ルーティングは上書きしないでください。
{
"log": {
"loglevel": "warning"
}
}
ポート競合:ローカル待ち受けを確認し、サーバー側のポートは変更しない
bindエラーはローカル待ち受けの段階で発生します。リモート接続の失敗とは別の問題です。以下の数値は調査用の例で、すべてのv2rayNG環境における初期設定ではありません。「設定」に表示されるローカルポートと実際のログを確認してください。
エラー:bind: address already in use
原因:指定したアドレスの待ち受けポートが別のプロセスに使用されているか、カスタム設定内の複数のinboundが同じポートにバインドされています。
対処法:まず関連するサービスを停止して、もう一度試します。それでも失敗する場合は、完全な設定のinboundsを確認し、各項目のlisten、port、プロトコルを照合してください。
ログに127.0.0.1:10808のバインド失敗が明記されている場合は、ローカルSOCKSポートを未使用の10818に変更して再起動する方法があります。そのSOCKSポートを利用するほかのアプリも、同じポートに変更してください。ノード編集画面のリモートポートだけを変更しても、ローカル待ち受けは解放されません。正しいノード設定を壊すおそれもあります。
要点:アドレスがどちら側か確認してからポートを変更
エラーに127.0.0.1とbindが含まれている場合は、まずスマートフォンのローカル待ち受けを確認します。サーバーアドレスと接続タイムアウトが示されている場合は、リモート接続を調べます。両方を同時に変更しないでください。
キーの誤記とコアの対応状況:JSONが正しいだけでは不十分
JSONを解析できても、すべての値をXrayが受け付けるとは限りません。たとえばstreamSettingsのnetworkには、コアが対応するトランスポート名を指定します。WebSocketの場合はwsであり、任意にwebsocketと書くことはできません。クライアント画面に表示されるプロトコル名が、設定内の文字列と一致するとも限りません。
- 大文字・小文字を確認:
streamSettings、serverName、wsSettingsは設定仕様どおりに記述します。似た綴りから推測しないでください。 - フィールドの型を確認:真偽値は
trueまたはfalseとし、引用符を付けて文字列にしないでください。ポートは通常、数値で指定します。 - 配置する階層を確認:TLSの
serverNameは対応するtlsSettings内に記述します。outboundオブジェクトの最上位に移動しないでください。 - パラメーターの組み合わせを確認:VLESSとVMessはプロキシプロトコル、WebSocketはトランスポート、TLSはセキュリティ層です。読み込み時にはそれぞれを個別に確認し、互いに置き換えないでください。
以下はWebSocketとTLSの構造を確認するための例です。ドメイン名とパスはサンプル値のため、実際にはサーバー側の設定と一致させてください。このオブジェクトだけでは完全なoutbound設定になりません。
{
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "example.com"
},
"wsSettings": {
"path": "/tunnel",
"headers": {
"Host": "example.com"
}
}
}
}
未知のフィールドがあっても、必ず起動エラーになるとは限りません。読み込み時に無視され、設定したつもりの項目が反映されないことがあります。一方、新しいパラメーターを非対応の古いコアに渡すと、設定の構築に失敗する場合があります。更新前にクライアントとコアの情報を記録し、元の設定を保存してください。更新後はまず元のノードをテストし、プロトコルとルーティング全体を同時に変更しないようにしましょう。
通信・証明書のエラー:通常は起動後に発生
コアがローカル待ち受けを開始し、Webページにアクセスしたときだけ次のエラーが出る場合は、JSONのカンマを調べ続ける必要はありません。まずノードのアドレスとリモートポートを確認し、TLS、セキュリティ設定、通信設定を照合します。以下はよくあるエラー例です。ログの先頭部分や付加される文言は、コアのバージョンによって異なります。
エラー:websocket: bad handshake
原因:WebSocketのハンドシェイクで期待した応答がありません。パス、Host、リモートポート、リバースプロキシの転送設定が一致していない場合によく発生します。
対処法:サーバー側から提供された情報と照らし合わせ、path、Host、TLSの有効・無効を確認してください。「ハンドシェイク」という表示だけを見てUUIDを変更しないでください。
エラー:x509: certificate has expired or is not yet valid
原因:証明書の有効期間が一致していません。サーバーの証明書が期限切れの場合も、スマートフォンの日時が間違っている場合もあります。
対処法:まずAndroidの「日付と時刻」で自動設定を有効にし、現在の日付を確認します。日時が正しいのにエラーが続く場合は、サービス提供元に証明書を確認してもらってください。
エラー:connection refused
原因:接続が明示的に拒否されています。接続先ポートでサービスが待ち受けていないか、途中の機器が拒否応答を返している可能性があります。
対処法:エラーに表示された接続先アドレスとポートを確認し、サーバー側の待ち受け状態を確認します。ローカルSOCKSポートを変更しても、リモート側の接続拒否は解決しません。
エラー:i/o timeout
原因:ネットワーク処理が制限時間内に完了しませんでした。このメッセージだけでは、DNS、接続経路、サーバーのどこに問題があるか判断できません。
対処法:エラーの直前に記録された処理対象を残し、ドメイン名の解決、接続の確立、ハンドシェイクのどこで止まるかを切り分けます。同じ設定のままWi-Fiとモバイル通信を切り替えて比較してください。
TLSのserverNameは、サーバー名に関するハンドシェイクと証明書検証に使われます。WebSocketのHostはHTTP層のリクエストに使われます。両者が同じ場合もあれば、サーバーの構成によって異なる場合もあります。エラーを消すために証明書の検証を無効にしないでください。ドメインや証明書の設定ミスが隠れてしまいます。
修正後に再テスト:記録を残し、手当たり次第に変更しない
設定を1か所変更したら、サービスを停止して古いログを消去し、再接続します。まずコアが動作し続けることを確認し、次にWebページへ一度アクセスして、そのリクエストで新しいエラーが発生していないか調べます。サブスクリプションの更新でノードが再生成されると、手動変更が上書きされることがあります。「今は使える」とだけ覚えるのではなく、変更した理由を記録してください。
ログにwarningばかり出ます。すべて解消すべきですか?
すべての警告を起動失敗とみなす必要はありません。まず時刻を手がかりに今回の接続に関するエラーの流れを特定し、サービスが終了したか、リクエストが失敗したかを確認します。現在の症状に関係する警告だけに対処し、余計な変数を増やさないようにしてください。
サブスクリプションの読み込みに成功したのに、起動できないのはなぜですか?
読み込みに成功したということは、クライアントがサブスクリプションの内容を受け付けたことを示すだけです。生成されたすべてのパラメーターに現在のコアが対応しているとは限りません。まずノードを1つ選んで問題を再現し、ログのプロトコルやフィールドに関するエラーを確認してから、クライアントのバージョンとノードの要件を照合してください。
JSONの行番号が表示されない場合、エラー箇所はどう探せばよいですか?
カスタム設定の場合は、まずローカルエディターでコピーを整形し、ログに記載されたフィールドを検索します。通常のノード設定の場合は、ノード編集画面に戻って該当パラメーターを確認してください。行番号を探すために設定全体をむやみに書き換えないでください。
クライアントを再インストールしたほうが早いですか?
まず設定をバックアップし、ログをコピーしてください。ポート競合、サーバー証明書、サブスクリプションのパラメーター誤りは、再インストールしても自動では直りません。アプリのデータに問題があると確認でき、復元に必要な情報も保存できた場合に限り、データの消去や再インストールを検討してください。
最後に、クライアントのバージョン、使用中のコア情報、最初に発生したエラーの全体、変更した項目、再テストの結果を簡潔に記録しておきましょう。同じエラーが再発しても、以前の問題が戻ったのか、次の段階で新たな問題が起きたのかを判断しやすくなります。