ノードの遅延テストに失敗した、TLSハンドシェイクが中断された、証明書が無効と表示されたv2rayN、v2rayNG、v2flyNGユーザー向けの記事です。システム時刻、ノードアドレスとSNI、証明書の有効期限、完全な証明書チェーン、クライアントのコアログの順に確認します。これにより、原因がローカル設定、サブスクリプションデータ、サーバー側の証明書設定のどこにあるか判断できます。
TLSエラーが発生する段階
V2RayまたはXrayがTLS接続を確立するとき、クライアントはまずノードのIPアドレスとポートへ接続し、SNIを含むClientHelloを送信します。サーバーはSNIに応じて証明書を選択し、クライアントは証明書の有効期限、ドメイン範囲、発行チェーン、システムの信頼状態を確認します。どれか1つでも通らなければ、プロキシプロトコルの通信が始まる前に接続が中断されます。
そのため、ログにTLSエラーが出たからといって、VMessやVLESSのユーザー識別情報が間違っているとは限りません。ユーザー識別情報、暗号化方式、フロー制御パラメータは通常、TLSハンドシェイク完了後の通信で使われます。トラブル対処ではまず証明書層を確認し、UUID、ポート、通信方式、ルーティングルールを同時に変更して変数を増やさないようにしてください。
ステップ1:システム時刻とタイムゾーンを合わせる
証明書には明確な有効開始時刻と有効期限が設定されています。クライアントは端末の時計を使って現在時刻が有効期間内か判断するため、日付が1日ずれている、タイムゾーンが間違っている、スリープ復帰後に時刻が同期されていないといった状態では、有効な証明書がまだ有効でない、または期限切れと判定されることがあります。デュアルブート環境、長期間電源を切っていたデスクトップ、時刻の自動調整を無効にした端末では特に起こりやすい問題です。
エラー:x509: certificate has expired or is not yet valid
原因と対処:端末の時刻が証明書の有効期間外にあるか、サーバー側の証明書が実際に期限切れになっています。まずシステムの時刻自動調整を有効にして、すぐに同期してからクライアントのコアを再起動してください。時刻を正しくしてもエラーが続く場合は、サーバー側の証明書の日付を確認します。
エラー:certificate invalid
原因と対処:証明書の検証に失敗したことを示す一般的なメッセージです。ログの次の行にexpired、not yet valid、unknown authority、hostnameのどれが含まれているか確認し、該当する分岐に進んでください。
-
現在時刻を確認
信頼できる時刻情報と照らし合わせ、年、月、日、時、分を確認します。ずれが5分に達している場合は、ノードのパラメータを変更せず、まずシステム時刻を同期してください。
-
ローカルのタイムゾーンを確認
Windowsでは「設定」→「時刻と言語」→「日付と時刻」を開き、タイムゾーンが現在地と一致していることを確認し、時刻の自動設定を有効にします。
-
今すぐ同期を実行
「日付と時刻」ページで「その他の設定」を開き、今すぐ同期を実行します。ある検証では、7分12秒のずれを修正したところ、「証明書がまだ有効でない」という表示がすぐに消えました。
-
クライアントのコアを再起動
v2rayNのメイン画面で「サーバー」→「サービスを再起動」を実行し、現在のサーバーの遅延を再テストします。古い接続が失敗状態のまま再利用されるのを防げます。
Android端末でも、「日付と時刻」の自動設定とタイムゾーンの自動設定を確認する必要があります。分だけ手動で近い値に合わせても、日付やタイムゾーンが間違っていれば証明書の判定に影響するため確実ではありません。時刻を同期したら、v2rayNGまたはv2flyNGを完全に終了してから再度起動し、ノードをテストしてください。
ステップ2:SNI、serverName、ノードアドレスを確認
SNIは、TLSハンドシェイクでサーバーへ送信されるホスト名です。V2RayとXrayの設定では通常、serverNameで指定します。明示的に入力していない場合、コアがノードアドレスから推測することがあります。ノードアドレスがIPアドレスである、入口ドメインと証明書のドメインが異なる、サブスクリプション変換時にSNIが失われるといった場合、サーバーがデフォルト証明書を返し、ドメイン不一致が発生することがあります。
3つの項目を区別する必要があります。ノードアドレスは接続先、ポートは接続入口、serverNameはTLSハンドシェイクで申告するドメインを決めます。WebSocketのHostリクエストヘッダーはTLS確立後に送信されるため、SNIの代わりにはなりません。Hostを正しく設定してもserverNameが間違っていれば、証明書の検証は失敗します。
| 設定項目 | 適用される段階 | 正しい入力方法 | よくある間違い |
|---|---|---|---|
| アドレス | TCP接続の確立 | サブスクリプションに記載された入口ドメインまたはIPアドレス | コピー時に余分なスペースが入っている、または古い入口を使っている |
| ポート | サービス入口への接続 | ノード設定と一致させる(例:443) | TLS以外のポートをTLSポートとして使っている |
| serverName | TLS ClientHello | 証明書に含まれる完全なドメイン名を入力 | IPアドレスや古いドメインを入力する、または空欄のまま誤って推測される |
| Host | HTTPまたはWebSocketリクエスト | ノードのパラメータに従ってアプリケーション層のホスト名を入力 | HostがSNIを自動的に置き換えると思い込む |
エラー:x509: certificate is valid for node.example.com, not edge.example.net
原因と対処:現在のserverNameと証明書の対象ドメインが一致していません。ノードのTLS設定にあるserverNameを、サブスクリプションで指定された証明書のドメイン名に変更してください。ノードのメモや速度テスト用ドメインから推測してはいけません。
エラー:remote error: tls: handshake failure
原因と対処:サーバーが現在のハンドシェイクパラメータを受け付けていません。SNI、ポート、TLS設定と入口の不一致でよく発生します。アドレス、443ポート、通信のセキュリティ方式、serverNameを確認して再試行してください。
一般的なVLESS TLSアウトバウンド設定では、アドレスとserverNameが異なる場合があります。以下の例は項目の関係だけを示したものです。実際のアドレス、ユーザー識別情報、ポート、通信方式は、有効なサブスクリプションに従ってください。
{
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "edge.example.net",
"port": 443,
"users": [
{
"id": "11111111-2222-3333-4444-555555555555",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"security": "tls",
"tlsSettings": {
"serverName": "node.example.com"
}
}
}
]
}
ステップ3:証明書の有効期限と完全な証明書チェーンを確認
システム時刻が正しく、SNIも一致しているのにunknown authorityやunable to verify certificateが表示される場合は、サーバーが返す証明書チェーンを重点的に確認します。通常、サーバーはサイト証明書と必要な中間証明書を送信し、クライアントはシステムが信頼するルート証明書を使って検証します。中間証明書が送信されていないと、一部のキャッシュ済み証明書環境では一時的に使えても、別の端末では安定して失敗することがあります。
エラー:x509: certificate signed by unknown authority
原因と対処:クライアントがサイト証明書を信頼されたルート証明書までつなげられていません。システムの証明書ストアを更新し、サーバーが完全な中間証明書チェーンを送信しているか確認してください。サイト証明書1枚だけを配置してはいけません。
エラー:tls: failed to verify certificate
原因と対処:証明書の検証段階で失敗しています。同じ行の後半を確認し、hostname、expired、unknown authorityのどれに該当するかで、ドメイン、日付、信頼チェーンの問題を切り分けてください。
エラー:unexpected EOF during TLS handshake
原因と対処:相手側がハンドシェイク完了前に接続を閉じています。接続先が本当にTLSポートか確認し、サーバーのリバースプロキシが現在のSNIで接続を受け付ける設定になっているか確認してください。
コマンドライン環境がある場合は、OpenSSLで対象の入口が返す証明書チェーンを直接確認できます。-connectには実際の接続先アドレスとポートを指定し、-servernameにはSNIを指定します。2つを意図的に分けることで、入口ドメインと証明書ドメインが異なる設定を検証できます。
openssl s_client \
-connect edge.example.net:443 \
-servername node.example.com \
-showcerts
- 出力されたサイト証明書のサブジェクトドメインを確認し、
node.example.comが対象に含まれていることを確認します。 - 証明書のNot BeforeとNot Afterを確認し、現在時刻が有効期間内にあることを確認します。
- Certificate chainにサイト証明書と必要な中間証明書が含まれているか確認します。番号0の証明書1枚だけでは不十分です。
- 末尾の検証結果が成功しているか確認します。チェーンが不完全な場合は、サーバー側で中間証明書を補完してから入口の設定を再読み込みします。
- 複数のノードが同じ入口を共有して同時に失敗する場合は、クライアントのノードを1つずつ変更するのではなく、入口証明書の更新状況とリバースプロキシ設定を優先して確認します。
クライアント利用者がサーバー側の証明書チェーンを修復することは通常できません。この場合は、ノード名、テスト時刻、最初のエラーログ、使用したネットワークを記録し、サブスクリプションを1度更新して再テストしてください。異なるネットワークや端末でも同じチェーンエラーが出るなら、その情報をノード管理者に伝えて証明書の配置を確認してもらいます。
ステップ4:クライアントごとにTLSパラメータを確認
外部から証明書が正常に見えることを確認したら、クライアントに保存されたノードパラメータを確認します。v2rayNのデスクトップ版は通常Xrayコアと組み合わせて使い、v2rayNGもXrayコアを使用します。v2flyNGはV2Flyコアに対応します。コアによってログの表現は異なる場合がありますが、アドレス、ポート、通信のセキュリティ、SNI、システム時刻の5項目を確認する順番は変わりません。
-
単一ノードに固定
自動選択を一時停止し、安定してエラーを再現できるノードを1つ選びます。ノードのメモ、アドレス、ポート、通信方式、TLS serverNameを先に記録し、複数ノードの切り替えで判断が乱れないようにします。
-
コアの種類を確認
v2rayNで「設定」→「パラメータ設定」→「Coreタイプ」を開き、現在のプロトコルが想定したコアを使用しているか確認します。保存後、「サーバー」→「サービスを再起動」を実行します。
-
サーバーを編集
v2rayNのサーバー一覧でノードを選択して編集画面を開き、アドレス、ポート、通信プロトコル、トランスポート層セキュリティ、SNIを順に確認します。ノードのメモをserverNameにコピーしないでください。
-
Androidの設定を確認
v2rayNGまたはv2flyNGの設定一覧で対象ノードの編集画面を開き、「アドレス」「ポート」「トランスポート層セキュリティ」「SNI」を確認します。保存後、そのノードを再選択して接続を開始します。
-
サブスクリプションを更新して再テスト
手動で追加したノードは正常なのにサブスクリプションのノードだけ異常な場合は、サブスクリプションを更新してTLS項目を比較します。複数のサブスクリプショングループがある場合は、現在のノードが更新直後のグループに属しているか確認してください。
-
最初のエラーを確認
ログを消去または区切ってから1回だけ接続し、最初に出たcertificateまたはhandshakeエラーを優先して確認します。その後、エラーのキーワードに応じて該当する対処手順へ戻ります。
| 現象 | 優先して確認する項目 | 判断材料 |
|---|---|---|
| すべてのTLSノードが同時に失敗 | システム時刻、システムの証明書ストア、現在のネットワーク | 異なるサブスクリプションやドメインでも似た証明書エラーが発生する |
| 同じ入口がすべて失敗 | 証明書の期限、証明書チェーン、入口ポート | 複数のノードアドレスまたはSNIが同じサービス入口を指している |
| 1つのノードだけ失敗 | serverName、アドレス、ポート、サブスクリプション項目 | 同じ端末とネットワークで他のTLSノードは正常 |
| サブスクリプション更新後に失敗し始めた | 新旧設定の項目差分 | 手動で残した古いノードは接続できる |
ステップ5:証明書、ネットワーク、プロトコルの問題を切り分ける
ログにhandshake failedと出ても、原因が証明書とは限りません。接続先ポートがTLSを提供していない、ネットワーク途中で接続がリセットされた、サーバーの入口が待ち受けていないといった場合も、ハンドシェイクは途中で終了します。エラーにx509、certificate、hostname、expired、unknown authorityが明記されているか確認するのがポイントです。これらのキーワードがあれば証明書の確認を優先し、なければネットワークの到達性とサーバーの待ち受けを確認します。
一度に変更する変数は1つだけにすることをおすすめします。まず時刻を同期して再テストし、次にSNIを変更して再テスト、その後に証明書チェーンを確認し、最後にコアを更新するかノードを作り直します。ネットワーク、コア、ポートを同時に変更してサブスクリプションを再インポートすると、接続が復旧しても何が原因だったのか分からなくなります。
遅延テストはタイムアウトするのに、ログに証明書エラーがない場合は?
まずノードアドレスを名前解決できるか、対象ポートへ到達できるか、ローカルのプロキシポートが使用中でないかを確認します。ログにcertificate、x509、TLS verify関連の情報が出た場合だけ、証明書の確認に進んでください。
ブラウザーではドメインを開けるのに、ノードのハンドシェイクに失敗するのはなぜ?
ブラウザーでアクセスしたドメイン、入口アドレス、ノードのSNIは一致しない場合があります。ノードの実際の設定に合わせて-servernameを付けたテストを実行し、トップページが開くかどうかだけでなく、クライアントのserverNameも確認してください。
サブスクリプション更新後、一部のノードだけエラーになる場合は?
正常なノードと異常なノードを1つずつ選び、アドレス、443ポート、TLSの有効化、SNIを比較します。一部のノードだけが失敗する場合は、端末の共通設定よりも、特定の入口の証明書またはサブスクリプション項目が原因である可能性が高いです。
システム時刻は正しいのに、証明書がまだ有効でないと表示される場合は?
年、日付、タイムゾーン、時刻の自動調整がすべて正しいことを確認し、証明書のNot Beforeも確認します。時刻が正しい複数の端末で同じ結果になる場合は、サーバー側で現在有効な証明書を再配置する必要があることが多いです。
IPアドレスに変更したらドメイン不一致が発生した場合は?
アドレスにはIPアドレスを使用できますが、SNIには証明書の対象ドメインを入力する必要があります。サブスクリプションにserverNameが記載されていない場合は、ノードのメモから推測せず、完全な設定パラメータを再取得してください。
最終再テストのチェックリスト
設定を修正したら、クライアントの状態が「接続済み」になったかだけでなく、再現可能な一連のテストで結果を確認します。まずコアを再起動し、ノードの遅延テストを実行し、実際のWebページまたはアプリのリクエストを確認し、最後にログに新しいTLSエラーが出ていないか確認します。接続は成功しているのにWebページへアクセスできない場合、問題はTLS層を越えているため、システムプロキシ、DNS、ルーティング分岐、アウトバウンド設定を確認します。
- システムの日付、時刻、タイムゾーンが正しく、自動時刻同期を実行済みである。
- ノードアドレスにスペースや古いドメインがなく、ポートがサーバーの入口と一致している。
- トランスポート層セキュリティがサブスクリプションの設定どおり有効で、TLS入口に明示的なポートが指定されている。
serverNameが証明書の対象ドメインと一致し、ノードのメモやIPアドレスを誤入力していない。- WebSocketのHostとTLSのSNIを分けて確認し、2つの項目を同一視していない。
- 証明書が有効期間内にあり、サーバーが必要な中間証明書を送信している。
- サブスクリプション更新後、古いグループの同名設定ではなく新しいノードを使用していることを確認している。
- ログから最初の証明書エラーが消え、接続テストを3回連続して同じ結果で完了している。
この順番で確認すると、曖昧なhandshake failedを検証可能な具体的問題へ分解できます。時刻の異常は有効期限の判定に影響し、SNIの誤りは不一致の証明書を返し、チェーンの不備は信頼検証を中断させ、ポートや入口の誤りはハンドシェイク完了前に接続を切断することがあります。変更内容と再テスト結果を記録するほうが、クライアントを何度も削除したりノード設定を一括変更したりするより、根本原因を見つけやすくなります。