V2Ray Subscription Formats: Base64, JSON Configs & Share Links

Learn how Base64 subscriptions, full JSON configs, and vmess:// and vless:// links are structured, and how to import, export, and convert them in v2rayN and v2rayNG.

At a glance

A subscription URL fetches and updates nodes; Base64 encodes data; a share link describes one node; and a full JSON file tells the core how to run. This guide is for anyone whose import failed after copying data or who needs to move settings to another device. Identify the format, choose the right import option, then check for transport, TLS, routing, and DNS settings that may not carry over.

First, distinguish the subscription URL, response body, and node links

“V2Ray subscription” is not a single file extension. A typical subscription URL is an HTTPS address with an access token. The client requests that URL to retrieve a list of nodes. The response body may contain share links on separate lines, or those links may be encoded together as Base64. The URL is the retrieval endpoint; the response body is the data to parse. Don’t paste one where the other belongs.

Data typeHow to identify itWhat it usually containsWhere to import it
Subscription URLHTTPS address, possibly with an access tokenEndpoint for remote updatesSubscription group settings
Base64 subscription bodyEncoded text that often decodes to protocol links on separate linesParameters for multiple nodesSubscription parsing; decode first for manual processing
Share linkvmess://、vless://、trojan://One node and some connection parametersImport from clipboard
Full core JSON configFields such as inbounds and outboundsInbound and outbound settings, plus optional routing and DNSCustom config import

Don’t assume something is a full config just because it starts with an opening brace. A common VMess share format also decodes to JSON, but it usually contains node fields such as add, port, id, and net—not the full core config structure. Some subscription APIs also return JSON specific to their management platform, which Xray cannot run directly.

Choosing a format: subscriptions for updates, links for individual nodes

Subscription URL and node list

Recommended

Best for everyday use when the provider maintains node addresses. Save the subscription URL in the client to fetch nodes again later. Base64 is just a common response encoding; it does not determine which protocols are supported.

Best for: using multiple devices, changing node addresses, and ongoing updates

Single share link

Easy to copy, scan, or use for a quick transfer. Once imported, it’s usually saved as a local node and won’t automatically sync if the provider changes its settings.

Best for: troubleshooting one node, a one-off transfer, or comparing settings field by field

Full native JSON config

Lets you specify local listening ports, outbound selection, and routing rules, but depends on the target core and its version. It’s a runtime config, not a universal backup format for different clients.

Best for: custom inbounds, complex routing, and preserving core-specific settings

Bottom line: decide whether you need ongoing updates

To keep up with provider updates, save the subscription URL on both devices. Export a share link only when you need to move one node. An exported node list won’t keep updating like a subscription.

Base64 does not provide privacy. Treat subscription URL tokens, UUIDs, and passwords in share links as credentials. Screenshots, logs, and clipboard sync can expose them. When troubleshooting, share field names—not real credentials with an online conversion site.

Base64 and share links: check the fields after decoding

A common Base64 subscription is a set of share links joined by line breaks and encoded as a whole. This is a different layer from the Base64 after vmess://: the former wraps a list of nodes, while the latter wraps one node’s JSON in a common VMess sharing format. After decoding the outer layer, check the prefixes first. Don’t repeatedly decode the entire result.

  1. Remove any leading or trailing whitespace introduced during copying, and keep a backup of the original text.
  2. If the text already starts with a protocol prefix, parse it as a link instead of decoding it again.
  3. If it’s an encoded response body, decode it once and check whether it contains protocol links on separate lines.
  4. If the result is an HTML login page or an error message, revisit how you fetched the subscription instead of trying to “fix the encoding.”

The VLESS link below uses a reserved example domain to illustrate its fields; it is not a working node. The port is 443, the transport is TCP, the security layer is TLS, and the fragment contains a display name.

vless://[email protected]:443?encryption=none&security=tls&type=tcp&sni=example.net#format-demo

Here, encryption=none is a VLESS protocol parameter; it does not disable TLS. The security layer is specified by security=tls. For a node using WebSocket, also preserve type=ws, the path, and Host. For REALITY, check the public key, short ID, server name, fingerprint, and other parameters. Whether a parameter is recognized depends on the client importer and selected core.

Import and export steps for v2rayN and v2rayNG

Menu labels may vary slightly between versions. The steps below use common menu names. Before you start, identify whether you have a subscription URL, a share link, or a full config file so you don’t add a remote URL to a regular server list. On desktop, also check which core is selected. v2rayNG on Android uses the Xray core; that doesn’t mean every format can be converted automatically.

Choose an import option based on the data type

Desktop: v2rayN
  • Subscription URL: Open “Subscription Group” → “Subscription Group Settings,” add a group, and enter the URL. Save it, then select “Update current subscription.”
  • Share link: Copy the full link, then select “Import batch URLs from clipboard” in the main window. The common shortcut is Ctrl+V.
  • Export a node: Select a regular node, then use the context menu option to share it or export its URL to the clipboard. Check the prefix in the result.
  • Full JSON: Use the option for adding a custom config server and select the file. Don’t paste the file contents into the subscription URL field.
Android: v2rayNG
  • Subscription URL: Open “Subscription Group Settings” from the menu, add a group, and save the URL. Return to the main screen and select “Update subscription.”
  • Share link: Tap “+” in the top-right corner → “Import from clipboard.” For a QR code, use the corresponding scan option.
  • Export a node: Open the share option for the node and choose copy to clipboard or QR code. In some versions, press and hold the node first.
  • Full JSON: From the “+” menu, select the option to import a config file. Custom config entries may have different sharing options from regular nodes.

You can use the same subscription URL on both clients, but node availability still depends on each client’s parser, core version, and network environment.

After importing, edit one node and check its address, port, UUID or password, then verify the transport and TLS settings. Select the node, start the service, and check the connection test and core logs. Seeing a node name means the text was recognized; it doesn’t confirm that remote authentication, certificates, and transport settings are correct.

Why you can’t turn a full JSON config into a single link

A share link mainly describes how to connect to one outbound. A full config also describes what traffic the device accepts, how it resolves domain names, and which outbound handles each request. A JSON file may contain multiple outbounds and domain-based routing rules, so no single link can represent all of it. Encoding the JSON as Base64 and adding a vmess:// prefix does not make it a valid VMess share link.

The Xray-style sample below listens on the local SOCKS port 127.0.0.1:10808. It uses an example domain and UUID, so it cannot connect to a real server. The example shows the additional structure a full config has beyond a node link. It is not a universal config template for V2Ray or other cores.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "example.net",
            "port": 443,
            "users": [
              {
                "id": "c2a183e4-5f61-4b8b-91ea-7a820ae42f61",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "example.net"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      }
    ]
  }
}

The remote connection fields in this example can be mapped to the VLESS link above, but the local SOCKS port and direct-routing rule for private IP addresses are not included in the link. The example’s geoip:private rule also requires the corresponding rule data in the runtime environment. When migrating a full config, check core syntax, required data files, and whether the port is already in use.

ConversionUsually preservedRequires extra handling
Link list → Base64 bodyOriginal link text and orderEncoding does not create a subscription update URL
Share link → client nodeProtocols and connection fields supported by the importerUnknown parameters may be ignored
Client node → share linkParameters supported by the target link formatLocal routing, DNS, and TUN settings
Full JSON → share linkRecognized parameters for one outboundOther outbounds, inbounds, rules, and core-specific fields

If conversion fails, troubleshoot the symptoms instead of repeatedly switching formats

Why does importing a subscription URL show “No valid config found”?

First, check whether you used “Import from clipboard” by mistake. Enter an HTTPS subscription URL in the URL field under “Subscription Group Settings,” save it, and update. If that still fails, check whether the response is a login page, an expired-token message, or a network timeout. A web page’s contents are not a node list.

Why is there still encoded text after decoding Base64?

Check the prefix first. If the decoded result starts with vmess://, the encoded part that follows may be the JSON for a single node—that’s normal. If you have a vless:// link, parse its URI parameters. Don’t blindly decode a block containing multiple links again.

The import worked, but the connection doesn’t. What did the conversion tool miss?

Compare the source data for the remote port, TLS server name, WebSocket path and Host, and required REALITY parameters. Stop the service, start it again, and check the new logs. If the local port is already in use, check the actual listening port—for example, 10808. Don’t change the remote 443 for this reason.

Why did my routing rules disappear when I moved to another device?

Sharing a node doesn’t sync the full app settings. Record routing, DNS, system proxy, or per-app proxy settings on the original device, then restore them on the new one. If you’re migrating a full JSON config, check that the target uses the same type of core and a compatible version; matching file extensions alone are not enough.

Run a small test first: migrate one node, confirm its fields match, start the service, and verify that it connects before handling the rest. If updating a subscription could overwrite changes, back up manually edited nodes first. Keep the original file so you can roll back if the conversion drops unknown fields. For more on routing and DNS, see the Advanced Configuration guide.

View client downloads