この記事は、サブスクリプションの読み込み失敗を調査したい方、ノードを移行したい方、設定構造を理解したい方に向けた内容です。まずレスポンスの内容を確認し、次にノード共有情報と完全な実行設定を区別し、最後にフィールドの対応状況を見ながら変換します。読み終える頃には、テキストがbase64形式の統合サブスクリプション、ネイティブJSON、またはVMess・VLESS・Trojan・Shadowsocksの共有リンクのどれに当たるかを判断できるようになります。
まず取得した形式を判別する
「サブスクリプション」は単一のファイル規格ではなく、配布方法の一つです。クライアントがサブスクリプションURLへアクセスすると、サーバーはbase64でエンコードされた複数行の共有リンクを返す場合もあれば、行単位のテキスト、JSON形式のノード一覧、特定クライアント向けの設定オブジェクトを直接返す場合もあります。URLが https:// で始まっていても、それは転送方式を示すだけで、レスポンス本文の構造までは分かりません。
単一の共有リンクは、1つのアウトバウンドノードを表します。代表的なプレフィックスには vmess://、vless://、trojan://、ss:// があります。通常はサーバーアドレス、ポート、認証情報、転送方式、TLSパラメータなどを含みます。統合サブスクリプションでは、複数の共有リンクを1つのレスポンスにまとめ、クライアントの更新時に再取得して該当するサブスクリプショングループを上書きします。
ネイティブJSON設定は、より広い範囲を扱います。inbounds、outbounds、routing、dns、log を同時に含められるため、リモートノードだけでなく、ローカルの待受ポート、ルーティングルール、DNS動作まで指定できます。完全なJSONを通常のサブスクリプションとして読み込んでも、クライアントが受け付けるとは限りません。
| 確認できる内容 | 可能性の高い形式 | 適した読み込み方法 |
|---|---|---|
| 長い英字・数字の文字列で、末尾が1つまたは2つの等号になる場合がある | base64形式の統合サブスクリプション | サブスクリプショングループまたはサブスクリプション設定 |
| 波括弧で始まり、inbounds、outboundsを含む | ネイティブJSON設定 | カスタム設定またはコア設定の読み込み |
| vmess://、vless://などのプレフィックスで始まる | 単一の共有リンク | クリップボードから読み込む、またはQRコードをスキャンする |
| 複数行の内容で、各行がプロトコルのプレフィックスから始まる | 全体をエンコードしていない統合リスト | クライアントのサブスクリプション解析機能による |
結論:URLの末尾ではなく本文を確認する
サブスクリプションURLは .json で終わっていても、base64テキストを返すことがあります。ファイル拡張子のないAPIがJSONを返す場合もあります。調査時は、実際のレスポンスの先頭数十文字、HTTPステータス、レスポンスタイプを確認してから、適切な読み込み方法を選んでください。
base64形式の統合サブスクリプションを分解する
最も一般的な従来型のサブスクリプションは、複数の共有リンクを改行で連結し、その全体を1回base64エンコードする構造です。base64は文字エンコードであり、暗号化やフィールドの正当性検証を行うものではありません。正常にデコードできても、文字列を復元できたというだけで、すべてのノードが現在のコアで認識されるとは限りません。
標準base64の文字セットは、大文字・小文字の英字、数字、プラス記号、スラッシュで構成され、末尾は等号でパディングされることがあります。一部のサービスではURLセーフ形式を使い、プラス記号をハイフン、スラッシュをアンダースコアに置き換え、末尾のパディングを省略します。クライアントが標準の文字セットしか受け付けない場合、「サブスクリプションの内容が空」や「形式が無効」と表示されることがあります。
エンコード前の統合内容の例:
vmess://eyJ2IjoiMiIsInBzIjoiV00tMDEiLCJhZGQiOiJleGFtcGxlLmNvbSJ9
vless://[email protected]:443?encryption=none&security=tls&type=ws&path=%2Fedge#VL-01
trojan://[email protected]:443?security=tls&sni=example.com#TR-01
処理の順序:
HTTPレスポンス本文 → 前後の空白を除去 → 全体をbase64デコード → 改行で分割 → 各プロトコルリンクを解析
- 空白文字を確認:本文先頭のUTF-8 BOM、コピー時に混入したスペース、余分な空行は、厳密なパーサーに影響することがあります。
- パディングを確認:base64の長さは通常、4文字単位に分割できる必要があります。パディングが欠けている場合は、余りに応じてパーサーが補えることもありますが、途中の文字を勝手に削除してはいけません。
- 改行を確認:サーバーはLFまたはCRLFを使用することがあります。安全な分割処理では両方の改行を扱い、空行を除外してください。
- 二重エンコードを確認:1回目のデコード後もbase64らしい文字列がまとまって残っていても、すぐに再度デコードすべきだと判断しないでください。まず、サーバー側で追加のラッピングが行われていないか確認します。
VMessの共有リンク自体も、「プレフィックス+base64形式のJSON」という構造を採用することが多いため、統合サブスクリプションでは二重エンコードになる場合があります。外側はノード一覧を包むために使われ、内側はVMessの共有形式です。外側をデコードした後は、行ごとのリンクの段階で止め、各 vmess:// の後ろにある内容を個別にデコードします。VLESSとTrojanは通常URIのクエリパラメータを使うため、リンク全体をbase64デコードする必要はありません。
ネイティブJSONをノード一覧と同一視できない理由
ネイティブのV2RayまたはXray JSONは、コアの実行設定です。データがどのローカル入口から入り、どのルーティングルールに一致し、どのアウトバウンド接続へ渡されるか、さらにドメインをどのように解決するかを定義します。1つのアウトバウンドノードは outbounds 配列の1要素にすぎません。完全な設定には direct、block など複数のアウトバウンドタグが含まれることもあります。
次の簡略化した例では、構造の階層を示しています。127.0.0.1:10808 で待ち受けるSOCKSインバウンドがローカルの通信を受け取り、proxy という名前のVLESSアウトバウンドがリモートの443番ポートへ接続します。実際の利用時には、転送層、TLS、REALITYのパラメータも streamSettings に記述します。
{
"inbounds": [
{
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"encryption": "none"
}
]
}
]
}
}
]
}
共有リンクまたはサブスクリプション
おすすめクライアントがローカルのインバウンド、ログ、基本的なルーティングを生成し、ノードにはリモート接続に必要なフィールドだけを持たせます。移行の負担を抑えやすい方法です。
適する用途:v2rayN、v2rayNG、v2flyNGで日常的なノードを管理する
ネイティブJSON
インバウンド、アウトバウンド、DNS、ルーティング、ポリシーを完全に制御できますが、対応するフィールドはコアによって異なる場合があります。
適する用途:カスタムルーティングやコアの動作を細かく制御する
クライアントのバックアップ
ノード以外に、サブスクリプショングループ、画面設定、ローカルデータベースの情報などが保存されることもあり、通常は同じクライアントでの復元にのみ適しています。
適する用途:同一クライアントのバージョン間で設定を移行する
JSONから共有リンクを抽出するとき、address、port、id だけをコピーしてはいけません。streamSettings.network、security、WebSocketのパス、HTTP Host、gRPCのserviceName、TLSのserverName、さらにREALITYのpublicKey、shortId、fingerprintも読み取る必要があります。重要なフィールドを1つでも欠かすと、構文は正しくてもハンドシェイクに失敗するリンクになる可能性があります。
逆方向の変換でも情報は失われます。単一の共有リンクでは、複雑な routing.rules、DNS hostsのマッピング、複数のインバウンドポート、ロードバランサー、チェーンプロキシなどを完全に保持できないことが一般的です。共有リンクを読み込むと、クライアントは独自のテンプレートでローカル部分を再生成するため、元のJSONの動作をすべて復元するわけではありません。
結論:変換の境界はリモートのアウトバウンドに置く
クライアント間でノードを移行する場合は、サーバー側のアウトバウンドに必要なフィールドだけを変換します。DNS、ルーティング分岐、複数のインバウンドを維持したい場合は、ネイティブJSONを移行し、移行先のコアが各設定セクションに対応していることを確認してください。
VMess、VLESSなどの共有リンクにおけるフィールドの違い
VMessの一般的な共有形式では、JSONオブジェクトをエンコードしたものを vmess:// の後ろに置きます。主なフィールドには、バージョン v、備考 ps、アドレス add、ポート port、ユーザー識別子 id、追加ID aid、暗号化方式 scy、転送ネットワーク net、偽装タイプ type、Host、パス、TLS、SNI、ALPN、フィンガープリントがあります。この形式はクライアントエコシステムの中で長年拡張されてきたため、新しいフィールドの一部は古いクライアントでは無視されることがあります。
VLESSは標準URIに近い形式です。ユーザー情報の位置にはUUID、ホストとポートにはサーバーアドレス、クエリパラメータには転送方式とセキュリティ層、ハッシュ記号以降のフラグメントにはノード名を記述します。VLESSの encryption は通常 none です。これはTLSのオン・オフではなく、TLSやREALITYなどのセキュリティ方式は security パラメータで指定します。
| 共有フィールド | 意味 | よくあるミス |
|---|---|---|
| address / add | リモートサーバーのドメイン名またはIPアドレス | コピー時にプロトコルのプレフィックスやパスが混入する |
| port | リモートの待受ポート(例:443) | ローカルの10808ポートを誤って入力する |
| id | VMessまたはVLESSのユーザーUUID | 文字の欠落、空白の混入、誤ったユーザーの使用 |
| type | 転送方式(例:tcp、ws、grpc) | サーバー側の転送設定と一致しない |
| security | 転送時のセキュリティ方式(例:tls、reality、none) | プロトコル固有の暗号化フィールドと混同する |
| sni / serverName | TLSハンドシェイクで使用するサーバー名 | IPアドレスを入力する、またはサーバーが要求するドメイン名を省略する |
| path | WebSocketのHTTPパス | スラッシュまたはパーセントデコードの段階を誤る |
| flow | VLESSのフロー制御方式(例:xtls-rprx-vision) | 通常のTLSノードにVisionを誤って設定する |
| pbk / sid | REALITYの公開鍵とshortId | サーバー側の秘密パラメータをクライアント側のフィールドに入力する |
VLESSリンクの構造例:
vless://UUID@サーバー:ポート
?encryption=none
&security=reality
&type=tcp
&sni=ハンドシェイク用ドメイン
&fp=chrome
&pbk=REALITY公開鍵
&sid=shortId
&flow=xtls-rprx-vision
#ノード名
Trojanリンクではユーザー情報の位置にパスワードを置き、その後ろに security、sni、type、path などのクエリパラメータを追加できます。Shadowsocksの共有リンクでは、主に暗号化方式、パスワード、アドレス、ポートを表します。拡張された転送パラメータへの対応状況は、具体的な形式に依存します。変換ツールが基本フィールドしか認識しない場合、ノード認証は残ってもプラグインや転送設定が失われることがあります。
URI内のノード名、パス、Hostはパーセントエンコードされている場合があります。たとえば空白は %20、クエリパラメータ内のスラッシュは %2F と表記されることがあります。正しく処理するには、リンク全体に文字列置換を繰り返すのではなく、URIの規則に従って各構成要素を解析します。ハッシュ記号、疑問符、区切り文字を早い段階でデコードすると、フィールドの境界が変わる可能性があります。
3種類の形式を安全に変換する手順
変換の第一の目的は、テキストの見た目を一致させることではなく、接続に必要なフィールドを保持することです。まず元の形式を特定し、次に統一したノードデータモデルを作成します。少なくともプロトコル、アドレス、ポート、認証、転送方式、セキュリティ層、備考を記録してください。最後に、移行先のクライアントまたは生成ツールで目的の形式として出力します。
元の内容を判別する
レスポンスの冒頭、プロトコルのプレフィックス、JSONのトップレベルキーを確認します。サブスクリプションURLの場合は、まずHTTPステータスが200であることを確認し、レスポンス全体をbase64デコードする必要があるか判断します。
ノードを分割する
統合サブスクリプションはLFまたはCRLFで行分割し、空行を除外します。各リンクはプロトコルのプレフィックスに応じたパーサーで処理し、VLESSのパラメータをVMessに流用しないでください。
フィールドを統一する
サーバー、ポート、ユーザー識別子、転送方式、TLSまたはREALITYのパラメータを統一的に保存し、WebSocket path、gRPC serviceName、SNIはそれぞれ個別に保持します。
コアを確認する
v2rayNで「設定」→「パラメータ設定」→「Coreタイプ」を開き、選択したコアがノードで使用するプロトコル、REALITY、XTLS Visionのフィールドに対応していることを確認します。
読み込んでテストする
まず1つのノードだけを読み込み、コアのログにunknown field、failed to find an available destination、TLS handshakeなどのメッセージが出ていないか確認してから、一括変換を行います。
v2rayNでは、通常サブスクリプションをサブスクリプショングループに追加してから、すべてのサブスクリプションを更新します。単一の共有リンクはクリップボードからの読み込みが適しています。完全なJSONを読み込む場合は、クライアントが提供するカスタム設定機能を使い、JSONファイルのURLを通常のサブスクリプションURL欄に直接入力しないでください。読み込み後は、アクティブなサーバーを選択し、システムプロキシまたは必要なTUNモードを有効にします。
v2rayNGとv2flyNGでは、サブスクリプション設定がリモートURLと更新結果を保存し、クリップボードからの読み込みが単一の共有リンクを処理します。v2rayNGはXrayコア、v2flyNGはv2flyコアを使用します。通常のVMess、VLESS、Trojan、Shadowsocksへの対応範囲や、新しい転送フィールドの受け入れ方は完全には同じではありません。移行後は、ノード名が表示されたかだけで判断せず、ノード詳細を開いて各項目を確認してください。
結論:まず1つを変換してから、サブスクリプション全体を処理する
単一ノードで、読み込み、コアの起動、実際の接続の3項目を検証すれば、フィールドの対応付けに関する問題をすばやく見つけられます。数十個のノードをいきなり変換すると、ノード名の重複、一部プロトコルの非互換、ログの混在によって調査の負担が増します。
サブスクリプション読み込み後に空になる場合の確認手順
読み込み後に一覧が空でも、サブスクリプションにノードがないとは限りません。ネットワーク要求、レスポンスのデコード、行単位の認識、プロトコル互換性、グループ表示のいずれかの段階で問題が起きている可能性があります。有効な調査は前段階から順に進め、クライアント設定を何度も削除するのは避けてください。
サブスクリプション要求が実際に本文を返していることを確認します。ログインページ、レート制限の案内、HTMLのエラーページが返っている可能性もあります。ページが200を返していても、アクセストークンの期限切れによって案内文が出力されることがあります。レスポンスが <html や <!doctype で始まる場合、base64デコードやプロトコル解析でノードが生成されないのは当然です。
サブスクリプション更新がタイムアウトするときは?
まず、端末からサブスクリプションのドメインへアクセスできることを確認します。直接接続で利用できない場合は、既存の利用可能なノードに接続してから、サブスクリプション設定でプロキシ経由の更新を有効にします。同時に、端末の時刻とサブスクリプションURLが完全にコピーされているかも確認してください。
更新は成功したのにノード一覧が空なのはなぜ?
更新ログで追加されたノード数を確認し、レスポンスのデコード後に vmess://、vless:// などのプレフィックスが現れるか確認します。JSONしか見つからない場合は、それがノード配列なのか、inboundsとoutboundsを含む完全なコア設定なのかを確認してください。
一部のノードしか読み込まれない場合は?
読み込まれなかったノードをプロトコルと転送方式で分類し、URLセーフbase64、REALITYパラメータ、gRPC serviceName、備考内の特殊文字を重点的に確認します。古いクライアントでは、認識できないフィールドやレコード全体がスキップされることがあります。
ノードはあるのにコアの起動に失敗する場合は?
v2rayNで「設定」→「パラメータ設定」→「Coreタイプ」を開いてコアを確認し、コアのログにある最初のエラーを確認します。ポートが使用中の場合は、ローカルの10808などの待受ポートを調べます。フィールドエラーの場合は、ノード編集画面で転送方式とセキュリティ層を確認してください。
更新後に手動変更が上書きされるのはなぜ?
サブスクリプションのノードは通常、リモートの内容によって管理されるため、再更新時にローカルのフィールドが上書きされることがあります。変更を長期的に保持したい場合は、ノードを独立したグループへコピーするか、元のサブスクリプション側で該当パラメータを修正してください。サブスクリプショングループ内の一時的なコピーだけを編集するのは避けましょう。
- リクエスト層:ステータスコード、リダイレクト、レスポンスサイズ、アクセストークンの有効性を確認します。
- エンコード層:標準base64、URLセーフbase64、パディング、UTF-8テキストが正しく処理されていることを確認します。
- 構造層:デコード結果が行単位の共有リンク、ノード配列、完全なコア設定のどれであるかを確認します。
- プロトコル層:VMess、VLESS、Trojan、Shadowsocksのプレフィックスと必須フィールドを確認します。
- コア層:Xrayまたはv2flyコアが、使用するセキュリティ方式、転送方式、flowに対応していることを確認します。
- 実行層:ローカルポートの競合、システムプロキシ、TUNモード、ルーティング分岐、コアのログを確認します。
サブスクリプションをデコードでき、共有リンクも単独で読み込めるのに、一括更新では空になる場合は、レスポンス形式がクライアントのサブスクリプションパーサーの想定と異なることがよくあります。たとえばサーバーがJSON配列を直接返しているのに、クライアントがbase64形式の複数行リンクとしてのみ処理しているケースです。この場合はサブスクリプションの出力形式を変更するか、そのJSON構造を明確にサポートする読み込み方法を選択してください。
ノードを読み込めるのに接続できない場合は、base64の調査を続ける必要はありません。この時点でエンコード処理は完了しており、問題はアドレス、ポート、UUID、パスワード、SNI、WebSocket path、gRPC serviceName、REALITY publicKey、shortId、flowにある可能性が高いです。コアのログにある最初のハンドシェイクエラーから順に確認する方が、サブスクリプションを繰り返し更新するより効果的です。
形式の選び方と長期運用のポイント
v2rayN、v2rayNG、v2flyNGで複数のノードを日常的に管理する場合は、サブスクリプションと共有リンクを組み合わせると更新しやすくなります。クライアントがローカルのインバウンド、システムプロキシ、基本ルーティングを生成し、サブスクリプション側ではリモートノードだけを管理します。特定のノードを調整するときは、次回更新でローカルの変更が上書きされないよう、まずサブスクリプション元を修正してください。
複雑なDNS、ドメインまたはIP単位のルーティング、複数のインバウンドポート、チェーン型アウトバウンドが必要な場合は、ネイティブJSONが適しています。このような設定では、対象コアと対応バージョンを記録し、Coreタイプを切り替えた後にフィールドを再確認してください。Xrayとv2flyの設定構造には共通部分が多いものの、REALITY、XTLS Vision、一部の拡張機能はフィールド名だけで互換性を判断できません。
| 用途 | 推奨形式 | 管理のポイント |
|---|---|---|
| 複数ノードの定期更新 | 統合サブスクリプション | グループ、更新日時、レスポンス形式 |
| ノードを1つだけ一時的に共有 | 共有リンク | プロトコルフィールド、URIエンコード、備考 |
| ルーティングとDNSを細かく制御 | ネイティブJSON | コア互換性、設定階層、アウトバウンドタグ |
| クライアント間の移行 | 標準の共有フィールド | まず単一ノードで検証してから一括生成 |
設定を保存するときは、「ノードデータ」と「クライアントの状態」も区別してください。ノードデータにはアドレス、ポート、認証、転送パラメータが含まれます。クライアントの状態には、現在選択中のノード、サブスクリプショングループ、システムプロキシモード、TUN設定、ルーティングルールが含まれます。共有リンクだけをエクスポートしても後者は移行されません。これはエクスポートの失敗ではなく、形式上の境界です。
最終的には、次の簡単なルールで選べます。ノード一式を自動更新したいならサブスクリプション、ノードを1つ渡したいなら共有リンク、コアの完全な実行動作を再現したいならネイティブJSONを使います。変換する場合は、まず移行先の形式で表現できないフィールドを洗い出し、情報の欠落を受け入れるのか、クライアント側で再構築するのか、元の設定を保持するのかを判断してください。