This guide is for v2rayN, v2rayNG, and v2flyNG users who need to inspect subscription data, move a single node, or troubleshoot import failures. You’ll learn to distinguish bundled subscriptions, full configs, and share links, understand what can be converted, and import and verify each format in your client.
Each format solves a different problem
“Subscription” is often used as a broad term, but the data you receive may belong to one of three layers. A Base64 bundle wraps multiple share links; a VMess or VLESS share link usually describes one outbound node; native JSON can define a complete runtime config with inbounds, outbounds, DNS, logs, and routing rules. Identify the layer first, then choose the import method instead of trying buttons at random.
Seeing a long string of letters, numbers, and a few equals signs after opening a subscription URL in a browser does not mean the content is broken. It may be an entire text response encoded with Base64. If decoding produces lines beginning with vmess:// or vless://, it is a typical bundled subscription. Here, encoding only packages the text; it is not encryption and does not change the node parameters.
Base64 subscription bundle
RecommendedOne URL can return multiple nodes, allowing the client to replace the server list as a whole during updates—ideal for ongoing maintenance.
Best for: routine subscription updates and syncing node lists across devices
VMess or VLESS share link
Each link describes one node, making it easy to import temporarily, copy to another device, or compare parameter differences.
Best for: moving a single node, manual testing, and checking parameters
Native JSON configuration
It can express local listeners, multiple outbounds, DNS, and routing in one place. This is the most complete format, but it depends on kernel field compatibility.
Best for: precise traffic routing, server-side configurations, and advanced troubleshooting
| Format | Typical prefix | What it contains | Typical import result |
|---|---|---|---|
| Base64 bundle | No fixed protocol prefix | Multiple share links | Creates a list of server entries |
| VMess share link | vmess:// |
One VMess node | Creates one server entry |
| VLESS share link | vless:// |
One VLESS node | Creates one server entry |
| Native JSON | { |
A complete or partial kernel configuration | Runs or parses as a custom configuration |
Bottom line: identify the data layer before choosing a conversion method
Keep the subscription URL when you need to update a group of nodes over time; use a share link to move a single node; save native JSON when DNS, inbound ports, or routing rules matter. These are not merely different file extensions.
Inside a Base64 subscription bundle
A typical bundled subscription returns a Base64-encoded text response. After decoding, it usually contains UTF-8 text with one share link per line; line endings may be LF or CRLF. When updating, the client requests the URL, decodes the text, and parses each line according to its protocol prefix. Unrecognized lines are usually skipped, so “update succeeded but zero nodes appeared” often means the decoded protocol is unsupported by the current client, or the server returned a login page, notice, or other non-subscription content.
dmxlc3M6Ly9mNDdhZDQ4YS1hZWMxLTQwZTQtYTgzOC0wNjE2N2VhZDc4OTVA
ZXhhbXBsZS5pbnZhbGlkOjQ0Mz9lbmNyeXB0aW9uPW5vbmUmc2VjdXJpdHk9
dGxzJnR5cGU9d3MmcGF0aD0lMkZhcGkjVExTLVdTLUV4YW1wbGU=
The content above is only a format illustration. To check whether something is Base64, first see whether its characters are mostly within A-Z, a-z, 0-9, plus, slash, and equals signs, then decode it. Character appearance alone cannot prove validity, because ordinary random text may fit the same range. A better test is whether decoding produces readable text and whether each line begins with a supported protocol prefix.
A VMess share link itself often contains a layer of Base64 encoding. Its payload is generally a JSON object describing the address, port, user ID, transport, and TLS parameters. A VMess bundled subscription may therefore encode the single-node JSON into a vmess:// link, concatenate multiple links, and encode the complete bundle again. Troubleshoot one layer at a time; do not decode the entire subscription as though it were a single VMess node.
How VMess and VLESS share links describe a node
Share links are designed to let a client rebuild one outbound node. VMess commonly places a Base64-encoded JSON object after the protocol prefix; VLESS is closer to a standard URI, with the user ID in the user-info section, the server address and port in the host section, transport, security, and flow-control settings in the query string, and the text after the hash used as the node name. Both link types may contain sensitive connection credentials and should not be pasted into public pages or public logs.
- Read the protocol prefix to determine whether to use the VMess or VLESS parser.
- Extract the server hostname, port, and user ID, and verify that the port is an integer from 1 to 65535.
- Read the transport type, such as TCP, WebSocket, or gRPC, and parse the path or service name accordingly.
- Read the TLS, server name, and application-layer protocol settings instead of migrating only the address and port.
- Decode the node remark and process percent-encoding before displaying it in the server list.
VLESS URI structure
The example below uses a reserved domain that cannot be resolved; the focus is on field placement. security=tls sets transport security, type=ws selects WebSocket, path is the request path, and sni is the server name used during the TLS handshake. Handle parameter name case sensitivity according to the client implementation, and avoid manually rewriting unknown fields.
vless://[email protected]:443?encryption=none&security=tls&sni=edge.example.invalid&type=ws&path=%2Fproxy#TLS-WS-Example
VMess and VLESS cannot be converted by simply replacing the protocol name. Their authentication models and parameter sets differ, and fields such as VLESS flow have no direct VMess equivalent. Only when the server provides both inbound configurations can it generate two separately connectable share links; rewriting the URI alone does not add support for another protocol on the server.
How native JSON relates to client subscriptions
Native JSON targets the V2Ray or Xray kernel. Common top-level fields include log, dns, inbounds, outbounds, and routing. A share link can usually map only to one outbounds entry. If the JSON also contains routing rules based on domains, IPs, ports, or inbound tags, exporting it as a single-node link cannot preserve the original behavior.
Recommended approach: let subscriptions manage nodes and clients manage local policies
Desktop v2rayN
- Maintain the server list through a subscription group
- Set the local SOCKS port to 10808 when needed
- Store routing rules separately and test which rules match
Android v2rayNG or v2flyNG
- Import the same subscription URL
- Parse nodes within the client’s supported feature set
- Configure routing and DNS separately on each device
Node parameters can sync through the subscription; local listeners, app scope, and routing policies should be managed separately on each device.
A minimal configuration is not the same as a subscription
The JSON below defines one local SOCKS inbound and one VLESS outbound. Even if the outbound fields are converted into a share link, the listening address 127.0.0.1, port 10808, and routing behavior will not be included. The target client fills them in with its defaults or existing settings.
{
"inbounds": [
{
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "example.invalid",
"port": 443,
"users": [
{
"id": "f47ad48a-aec1-40e4-a838-06167ead7895",
"encryption": "none"
}
]
}
]
}
}
]
}
inboundsdetermines how local programs hand traffic to the kernel.outboundsdetermines which remote protocol carries traffic out, or whether it connects directly.routingselects an outbound based on domains, IPs, ports, and tags.dnsdetermines how names are resolved, but does not automatically become a node sharing parameter.
JSON exported by a client may also include generated tags, statistics policies, or kernel-specific fields. Before importing it into another client, confirm that the target client’s kernel and version recognize those fields. v2rayNG uses the Xray kernel, while v2flyNG uses the v2fly kernel; their support overlaps for basic VMess, VLESS, and common transports, but new fields and extensions should not be assumed to work identically.
Practical steps for importing, converting, and updating
For everyday use, let the client read the subscription URL directly instead of decoding it manually and importing nodes one by one. Direct subscriptions preserve the update path, so the client can fetch the list again when the provider changes node names, addresses, or ports. Manual conversion is best for inspecting content, moving a small number of nodes, or finding why a specific record failed to parse.
| Task | Recommended entry point | What to check afterward |
|---|---|---|
| Add a subscription in v2rayN | “Subscription Groups” → “Subscription Group Settings” → “Add” | After updating, check the group name and node count |
| Import a single node into v2rayN | Copy the share link, then choose “Servers” → “Import Batch URLs from Clipboard” | Verify the address, port, transport, and TLS parameters |
| Add a subscription in v2rayNG | Open “Subscription Group Settings” from the side menu, add the URL, and update | Confirm that the active group has switched to the new subscription |
| Import a single node into v2rayNG | Copy the link, tap “+” in the top-right corner, and choose “Import from Clipboard” | Open the node details and check the server name and transport |
| Import a subscription into v2flyNG | Open subscription group settings, enter the name and complete URL, then update | Confirm that the node protocol is supported by the v2fly kernel |
Menu labels may change between client versions, but the basic sequence remains the same: save the subscription URL, update it manually, then select a node and start the connection. During testing, do not rely only on an “active” status; also check core logs, actual latency, and whether the target site loads. A failed latency test does not always mean the node is unusable—the test endpoint may be unreachable or DNS resolution may be failing.
The subscription updated successfully. Why is the list still empty?
First confirm which group is selected under subscription groups, then check whether the update result says that zero records were parsed. If it is zero, copy the response into a local text tool and inspect it: after Base64 decoding, it should contain one share link per line, not a login page, error message, or HTML source.
What should I do if a copied VLESS link shows a format error?
Check that the link starts with vless://, that the user ID, domain, and port are complete, and that & in the query parameters was not truncated by a chat tool. Copy the original plain text again, and do not manually remove percent-encoding.
Why is the Base64 output garbled after decoding? Is the encoding incompatible?
First confirm that no trailing characters are missing, then try standard Base64 and the URL-safe variant separately. Decoded bytes are usually read as UTF-8; if the result is still unreadable, the content may be compressed, use another subscription protocol, or not be a bundled text response at all.
Can I paste complete JSON directly into the subscription URL field?
No. The subscription field requires a requestable URL, not configuration content. Import complete JSON through the client’s custom-configuration entry point, and check that its inbound port does not conflict with an existing program.
Why do two clients show different node counts for the same subscription?
Record the total after updating each client, then inspect the protocols and transport settings of skipped nodes. v2rayNG and v2flyNG use different kernels, so parsing or runtime results may differ when a field is supported by only one of them. Do not force a protocol conversion by merely renaming it.
Fields to preserve and security boundaries during conversion
A reliable converter should parse the input into a structured object and serialize it again in the target format, rather than performing string search-and-replace. At minimum, preserve the protocol, server address, port, user ID, transport type, TLS state, server name, path or service name, flow-control settings, and node remark. Missing any connection-critical field can produce a record that imports successfully but cannot connect.
- Copy the original content into a controlled local environment and determine whether it is a subscription response, share link, or complete JSON.
- Decode and parse it into a field object, then type-check the port, user ID, and required parameters.
- Filter fields according to the target client and kernel capabilities, and record anything that cannot be mapped.
- After generating the target format, parse it again and compare the address, port, security layer, and transport layer.
- Create a separate test group in the client without overwriting the original subscription that still works.
- After connecting, check the core logs and test DNS, TCP, and any required UDP scenarios separately.
Bottom line: preserve the original subscription before conversion and read fields back afterward
The safest acceptance test is not seeing “import successful,” but parsing the generated result again and comparing every field. Once the address, port, user ID, TLS server name, and transport path all match, proceed to connection testing.
Subscription URLs and share links may directly contain access credentials. When sharing screenshots for troubleshooting, obscure the full subscription URL, user ID, and authentication fields; when sharing logs, keep only the error type, time, and necessary network status. If a subscription URL has entered a public record, replace its credentials in the provider’s dashboard, delete the old URL from clients, and perform a full update.