V2Ray Subscription Formats Explained: Base64, Native JSON, and Share Link Conversion

Understand base64 subscription bundles, native JSON configurations, and individual share links—what their fields mean, which clients support them, and why imports fail.

At a Glance

This guide is for anyone troubleshooting failed subscription imports, migrating nodes, or trying to understand configuration structures. The key sequence is to inspect the response first, distinguish node-sharing data from a complete runtime configuration, and then convert based on supported fields. By the end, you can identify whether text is a base64 subscription bundle, native JSON, or a VMess, VLESS, Trojan, or Shadowsocks share link.

Identify the Format First

A “subscription” is not a single file specification but a distribution method. After a client requests the subscription URL, the server may return multiple share links encoded as base64, plain line-separated text, a JSON node list, or even a client-specific configuration object. A URL beginning with https:// only describes the transport method; it says nothing about the structure of the response body.

An individual share link describes one outbound node. Common prefixes include vmess://, vless://, trojan://, and ss://. It usually contains the server address, port, authentication details, transport, and TLS parameters. An aggregated subscription places multiple share links in one response, which the client downloads again during updates and uses to replace the corresponding subscription group.

A native JSON configuration covers much more. It can include inbounds, outbounds, routing, dns, and log, specifying not only remote nodes but also local listening ports, routing rules, and DNS behavior. A client may not accept a complete JSON file when it is imported as an ordinary subscription.

3 types
Aggregated subscriptions, native JSON, share links
4 prefixes
VMess、VLESS、Trojan、Shadowsocks
36 characters
Standard UUID length with hyphens
10808
Common local SOCKS listening port
What you see Most likely format Recommended import entry
A long string of letters and numbers, possibly ending with one or two equals signs Base64 aggregated subscription Subscription group or subscription settings
Starts with a curly brace and contains inbounds and outbounds Native JSON configuration Custom configuration or core configuration entry
Starts with a prefix such as vmess:// or vless:// Individual share link Import from clipboard or scan a QR code
Multiple lines, each beginning with a protocol prefix Aggregated list without overall encoding Depends on the client's subscription parser

Bottom line: inspect the response body instead of guessing from the URL suffix

Even a subscription URL ending in .json may return base64 text, while an endpoint without a file extension may return JSON. During troubleshooting, inspect the first few dozen characters of the actual response, its HTTP status, and its content type before choosing an import entry.

How to Decode a Base64 Subscription

The most common legacy subscription format joins several share links with newline characters, then base64-encodes the entire text once. Base64 is character encoding, not encryption, and it does not validate whether fields are correct. Successful decoding only means the characters can be restored; it does not mean every node will be recognized by the current core.

The standard base64 alphabet uses uppercase and lowercase letters, digits, plus signs, and slashes, with equals signs sometimes added as padding. Some services use the URL-safe variant, replacing plus with hyphen and slash with underscore while omitting padding. A client that accepts only the standard alphabet may show “subscription is empty” or “invalid format.”

Example of the aggregated content before encoding:

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

Processing order:
HTTP response body → trim surrounding whitespace → decode the entire base64 string → split by line breaks → parse each protocol link

VMess share links themselves often use a “prefix plus base64 JSON” structure, so an aggregated subscription may contain two encoding layers: the outer layer packages the node list, while the inner layer belongs to the VMess share format. After decoding the outer layer, stop at the line-by-line link stage, then decode the content after vmess:// separately for each link. VLESS and Trojan generally use URI query parameters and do not require base64-decoding the entire link.

Why Native JSON Is Not the Same as a Node List

Native V2Ray or Xray JSON is a core runtime configuration. It describes which local entry receives traffic, which routing rules match, which outbound connection handles it, and how domains are resolved. A single outbound node is only one item in the outbounds array; a complete configuration may also contain multiple outbound tags such as direct and block.

The abbreviated example below shows the hierarchy. A SOCKS inbound listening on 127.0.0.1:10808 receives local traffic, while the VLESS outbound named proxy connects to the remote server on port 443. In actual use, transport, TLS, or REALITY parameters are also placed in 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"
              }
            ]
          }
        ]
      }
    }
  ]
}

Share link or subscription

Recommended

The client generates local inbounds, logging, and basic routing. The node only supplies remote connection fields, making migration relatively simple.

Best for: managing everyday nodes in v2rayN, v2rayNG, and v2flyNG

Native JSON

Provides complete control over inbounds, outbounds, DNS, routing, and policies, but supported fields may vary between cores.

Best for: custom routing chains or precise core behavior

Client backup

May include subscription groups, interface preferences, and local database data in addition to nodes; it is usually suitable only for restoring the same client.

Best for: migrating settings between versions of the same client

When extracting a share link from JSON, do not copy only address, port, and id. Also read streamSettings.network, security, the WebSocket path, HTTP Host, gRPC serviceName, TLS serverName, and the REALITY publicKey, shortId, and fingerprint. Omitting any critical field can produce a syntactically valid link that still fails during the handshake.

Reverse conversion can also lose information. A single share link generally cannot fully carry complex routing.rules, DNS hosts mappings, multiple inbound ports, load balancers, or chained proxies. After importing a share link, the client regenerates these local parts from its own template rather than restoring every behavior of the original JSON.

Bottom line: treat the remote outbound as the conversion boundary

When migrating nodes between clients, convert only the fields required by the server outbound. If you need to preserve DNS, split routing, or multiple inbounds, migrate the native JSON and confirm that the target core supports every configuration section.

Field Differences Between VMess, VLESS, and Other Share Links

The common VMess share format encodes a JSON object and appends it after vmess://. Typical fields include version v, remark ps, address add, port port, user ID id, alter ID aid, encryption method scy, transport network net, camouflage type type, Host, path, TLS, SNI, ALPN, and fingerprint. This format has evolved across the client ecosystem for years, so older clients may ignore some newer fields.

VLESS is closer to a standard URI: the UUID goes in the user-info section, the server address and port identify the host, query parameters describe transport and security, and the fragment after the hash is the node remark. VLESS typically uses encryption set to none; this is not a TLS switch. TLS, REALITY, and other security methods are specified by the security parameter.

Share field Meaning Common mistake
address / add Remote server domain or IP address Protocol prefix or path accidentally included during copying
port Remote listening port, such as 443 Mistakenly entering the local port 10808
id VMess or VLESS user UUID Missing characters, spaces, or the wrong user
type Transport type, such as tcp, ws, or grpc Does not match the server transport
security Transport security method, such as tls, reality, or none Confusing it with the protocol's own encryption field
sni / serverName Server name used for the TLS handshake Entering an IP or omitting the domain required by the server
path WebSocket HTTP path Incorrect slash or percent-decoding level
flow VLESS flow control, such as xtls-rprx-vision Vision enabled by mistake on a standard TLS node
pbk / sid REALITY public key and shortId Putting server-private parameters into client fields
VLESS link structure:

vless://UUID@server:port
?encryption=none
&security=reality
&type=tcp
&sni=handshake-domain
&fp=chrome
&pbk=REALITY-public-key
&sid=shortId
&flow=xtls-rprx-vision
#node-remark

A Trojan link places the password in the user-info section and can likewise carry query parameters such as security, sni, type, and path. Shadowsocks share links mainly describe the encryption method, password, address, and port; support for additional transport parameters depends on the specific format. If a converter recognizes only the basic fields, it may preserve authentication while dropping plugin or transport settings.

Node remarks, paths, and Host values in URIs may be percent-encoded. For example, a space can appear as %20, and a slash in a query parameter may appear as %2F. Parse each URI component according to URI rules instead of repeatedly replacing strings across the entire link. Decoding hashes, question marks, or separators too early can change field boundaries.

A Reliable Workflow for Converting Between the Three Formats

The first goal of conversion is to preserve the fields required for a connection, not to make the text look identical. Identify the source format, build a unified node data model, and record at least the protocol, address, port, authentication, transport, security layer, and remark. Finally, let the target client or generator output the target format.

  1. Identify the source content

    Inspect the response start, protocol prefix, and top-level JSON keys. For a subscription URL, first confirm an HTTP 200 response and determine whether the entire response needs base64 decoding.

  2. Split the nodes

    Split aggregated subscriptions on LF or CRLF and filter blank lines. Choose a parser for each link based on its protocol prefix; do not apply VLESS parameters to VMess.

  3. Normalize the fields

    Store the server, port, user ID, transport type, and TLS or REALITY parameters consistently, while keeping the WebSocket path, gRPC serviceName, and SNI as separate fields.

  4. Check the core

    In v2rayN, open “Settings” → “Parameter Settings” → “Core Type” and confirm that the selected core supports the node's protocol, REALITY, or XTLS Vision fields.

  5. Import and test

    Import one node first. Check the core log for messages such as unknown field, failed to find an available destination, or TLS handshake errors before converting in bulk.

In v2rayN, subscriptions usually go into a subscription group, followed by an update-all-subscriptions action. Individual share links are better imported from the clipboard. To load a complete JSON configuration, use the client's custom-configuration capability instead of placing the JSON file URL in the ordinary subscription field. After importing, select the active server and enable the system proxy or the required TUN mode.

In v2rayNG and v2flyNG, subscription settings store the remote URL and update results, while clipboard import handles individual share links. v2rayNG uses the Xray core, while v2flyNG uses the v2fly core; their support for common VMess, VLESS, Trojan, and Shadowsocks configurations and newer transport fields is not identical. After migration, check each field in the node details instead of judging success only by whether the node name appears.

Bottom line: convert one node first, then process the full subscription

Use a single node to verify import, core startup, and an actual connection. This quickly exposes field-mapping problems. Converting dozens of nodes at once adds duplicate names, partial protocol incompatibility, and interleaved logs, making troubleshooting harder.

What to Check When an Imported Subscription Is Empty

An empty list after import does not mean the subscription contains no nodes. The failure may occur during the network request, response decoding, line-by-line detection, protocol compatibility check, or group display. Start with the earliest stage instead of repeatedly deleting the client's configuration.

First confirm that the subscription request returned a response body—not a login page, rate-limit message, or HTML error page. A page can return 200 while displaying a message because the access token has expired. If the response starts with <html or <!doctype, base64 decoding and protocol parsing will naturally produce no nodes.

What If a Subscription Update Times Out?

First confirm that the device can reach the subscription domain. If the direct route is unavailable, connect through an existing working node and enable proxy-based updates in subscription settings. Also check the system clock and make sure the subscription URL was copied in full.

Update Succeeded but the Node List Is Empty?

Check the number of newly added nodes in the update log, then see whether prefixes such as vmess:// and vless:// appear after decoding. If you see only JSON, determine whether it is a node array or a complete core configuration containing inbounds and outbounds.

Only Some Nodes Imported?

Group the missing nodes by protocol and transport type, paying special attention to URL-safe base64, REALITY parameters, gRPC serviceName, and special characters in remarks. Older clients may skip unrecognized fields or the entire record.

Nodes Exist but the Core Fails to Start?

In v2rayN, open “Settings” → “Parameter Settings” → “Core Type” to verify the core, then inspect the first error in the core log. For a port conflict, check local listening ports such as 10808. For field errors, return to the node editor and verify the transport and security layers.

Manual Changes Overwritten After an Update?

Subscription nodes are usually managed by remote content, so a later update can overwrite local fields. To keep changes long term, copy the node into an independent group or correct the relevant parameters in the source subscription instead of editing a temporary copy in the subscription group.

If the subscription decodes correctly and individual share links import successfully but bulk updates still produce an empty list, the response format may not match the client's subscription parser. For example, the server may return a JSON array while the client expects base64-encoded line-separated links. Adjust the subscription output format or use an import method that explicitly supports that JSON structure.

If a node imports but the connection fails, stop investigating base64. Encoding has already succeeded; the problem is more likely the address, port, UUID, password, SNI, WebSocket path, gRPC serviceName, REALITY publicKey, shortId, or flow. Checking each item against the first handshake error in the core log is more effective than repeatedly updating the subscription.

Format Selection and Long-Term Maintenance

When maintaining multiple nodes in v2rayN, v2rayNG, or v2flyNG, combining subscriptions with share links makes updates easier. The client generates local inbounds, the system proxy, and basic routing, while the subscription source maintains only remote nodes. When a node needs adjustment, fix it in the subscription source first to avoid having the local change overwritten on the next update.

Native JSON is a better fit for complex DNS rules, domain- or IP-based routing, multiple inbound ports, or chained outbounds. Record the target core and supported version, then recheck the fields after switching core types. Xray and v2fly share much of their configuration structure, but compatibility with REALITY, XTLS Vision, and some extensions cannot be inferred from field names alone.

Use case Recommended format Maintenance focus
Regular updates for multiple nodes Aggregated subscription Group, update time, response format
Sending one node temporarily Share link Protocol fields, URI encoding, remark
Precise routing and DNS control Native JSON Core compatibility, configuration hierarchy, outbound tags
Migration between clients Standard share fields Validate one node first, then generate in bulk

When saving configuration, distinguish between “node data” and “client state.” Node data includes the address, port, authentication, and transport parameters. Client state includes the selected node, subscription groups, system proxy mode, TUN settings, and routing rules. Exporting only share links will not carry over the latter; that is a format boundary, not an export failure.

Use this simple rule: choose a subscription to update a group of nodes automatically, a share link to pass along one node, and native JSON to reproduce complete core behavior. Before converting, list the fields the target format cannot express, then decide whether to accept the loss, have the client rebuild them, or retain the original configuration.

Go to Client Downloads Windows, macOS, Android, Linux