V2Ray Subscription Formats Explained: Base64, Native JSON, and Share Link Conversion
Learn how to distinguish Base64 subscriptions, native JSON configs, and individual share links, including the fields to preserve during conversion and each format's limits.
Separate encoding, containers, and protocols
When working with V2Ray subscriptions, the most common source of confusion is mixing up three layers: encoding, configuration containers, and proxy protocols. Base64 is a text-encoding method that converts raw bytes into transport-friendly characters. JSON is a structured data format that can store a complete core configuration or only the fields for a single node. VMess and VLESS are proxy protocols that define how the client and server exchange the information they need. These are different layers and cannot be treated as interchangeable.
A typical subscription response may look like one long string with no obvious separators. After decoding, it often becomes multiple share links on separate lines. In this case, Base64 is only the outer wrapper; the importable content is inside the decoded result. Other subscription URLs return JSON directly, which may contain a node array or a complete core configuration with inbound, outbound, routing, and DNS settings. Some URLs return one share link per line, such as vmess:// or vless://, without another outer encoding layer.
Identify the format from the outside in: first determine whether the HTTP response is plain text or JSON, then check whether the plain text needs Base64 decoding, and finally inspect whether the decoded content is a list of share links, a single-node object, or a complete configuration. A file extension, string length, or subscription URL suffix alone cannot reliably identify the content type.
How to identify and decode a Base64 subscription
Traditional Base64 subscriptions join multiple share links line by line and encode the resulting text as a whole. When refreshing a subscription, the client fetches the response body, attempts to decode it, splits the result on line breaks, and parses each URI separately. Line endings may be LF or CRLF, so a robust parser should support both while ignoring leading and trailing whitespace and blank lines.
The standard Base64 alphabet uses uppercase and lowercase letters, digits, plus signs, and slashes, with one or two equals signs sometimes added as padding. The URL-safe variant replaces plus and slash with hyphen and underscore, and may omit the final padding. Some subscription generators also prepend an invisible marker or return content with extra spaces. A converter that accepts only one alphabet may report a decoding error even when the subscription itself is valid.
Decoded content usually resembles the line-based structure below. This is a structural example only; the domain uses a reserved suffix and does not point to a reachable service:
vless://[email protected]:443?encryption=none&security=tls&type=ws&host=edge.invalid&path=%2Fconnect#Office
vmess://eyJ2IjoiMiIsInBzIjoiVGVzdCIsImFkZCI6Im5vZGUuaW52YWxpZCJ9
The first line is a VLESS share link with its parameters in the URI. After vmess://, the second line still contains encoded text that must be decoded again to reveal a single-node JSON object. In other words, the outer subscription and an individual VMess share link may each use Base64 once. Decoding only the subscription wrapper does not mean the node fields have been parsed. During repeated decoding, do not mistake an ordinary UUID, path, or remark for another encoding layer.
When decoding in a browser or at the command line, also check the text encoding. Node remarks are usually UTF-8; if a tool treats the result as another character set, non-ASCII remarks may become garbled while the server address, port, and UUID remain unaffected. Do not fix garbled text by deleting node fields. Keep UTF-8 intact and confirm that line breaks and URI percent-encoding remain unchanged before re-encoding.
Native JSON configuration structure and limits
A native V2Ray or Xray JSON configuration usually describes a runtime structure that can be passed directly to the core. It may include not only remote nodes, but also local listening ports, DNS, logging, routing rules, policies, and multiple outbounds. The following is a reduced structural example:
{
"inbounds": [
{
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "node.invalid",
"port": 443,
"users": [
{
"id": "11111111-2222-3333-4444-555555555555",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"wsSettings": {
"path": "/connect",
"headers": {
"Host": "edge.invalid"
}
}
}
}
]
}
In this type of configuration, inbounds determines how local applications connect to the proxy, outbounds describes how traffic is handled after leaving the client, routing selects the outbound for each flow, and dns controls name resolution. A share link usually covers only the information needed for one remote outbound. It cannot fully represent local listeners, complex traffic splitting, relationships between multiple outbounds, or DNS rules.
Some services design a custom “subscription JSON” object, such as one whose top level contains a node array, an update time, or a group name. This JSON is not a native core configuration; its field names and hierarchy are defined by the generator and client. Seeing curly braces does not mean the file can be passed directly to the core. First check for core structures such as inbounds and outbounds, or confirm that the client explicitly supports this subscription format.
v2rayN manages nodes, subscriptions, and routing, then generates the core runtime configuration from its interface settings. On Android, v2rayNG uses the Xray core, while v2flyNG uses the v2fly core. Even when all three recognize common share links, supported transport parameters may differ between core versions. When copying a complete JSON configuration from one client to another, recheck local listeners, log paths, and platform-specific settings.
Key fields that must survive format conversion
Whether converting a subscription list into share links, generating outbound JSON from a share link, or reducing a complete JSON file to single-node data, the essential task is to establish field mappings. A working connection depends on more than the address and port: identity, transport, security, and their related parameters matter too.
- Server address and port: Keep the domain name unchanged unless the configuration explicitly requires a fixed address. Replacing a domain with an address from one DNS lookup may bypass future DNS updates.
- User identity: VMess and VLESS commonly use a UUID. Preserve every character during copying, decoding, and re-encoding. Do not treat it as a number or change its format by removing hyphens.
- Transport network: TCP, WebSocket, gRPC, and other transports must match the server. If only the server and port are retained while the network type is lost, the client will usually fall back to its default and no longer match the original configuration.
- Transport parameters: The WebSocket path and Host, the gRPC service name, and similar fields are part of the connection. An empty string, the root path, and a missing field can have different meanings, so do not merge them during conversion.
- Security-layer parameters: Map TLS status, server name, and related options accurately. The server address and the name used for the secure handshake may differ; do not overwrite one simply because they look similar.
- Node remark: A remark does not determine connectivity, but it affects node identification and grouping. Store it as UTF-8 and apply correct percent-encoding in the URI fragment.
When a complete JSON configuration is converted into a share link, routing and DNS are among the most obvious losses. Suppose the configuration has three outbounds, proxy, direct, and block, with rules that send different domains to different outbounds. Exporting a single link for proxy preserves only that remote connection. Re-importing the link will not automatically recreate the other two outbounds or their rules.
Reverse conversion has limits too. A share link can produce one remote outbound, but the local inbound port, log level, DNS servers, and routing mode still need to be supplied by the client. v2rayN, v2rayNG, and v2flyNG generally combine node data with their own defaults, so successful import of the same link on different devices does not guarantee identical generated runtime configurations.
Layered troubleshooting for subscription import failures
When you see “subscription cannot be parsed” or no nodes appear after import, troubleshoot in this order: retrieval, decoding, splitting, protocol parsing, and connection verification. Changing every field at once hides the real cause and can easily break a usable configuration.
Step 1: Confirm that the subscription body was retrieved
A subscription URL may return a plain notice page because authorization expired, the network redirected the request, or the server failed. The notice is still text, but it is neither Base64 nor JSON. Check whether the response begins with page markup, an error message, or a login prompt, and confirm that the client receives the same authentication requirements as the browser environment.
Step 2: Determine whether an outer decoding layer is required
If the body consists of Base64 characters, try decoding it in both standard and URL-safe forms. The result should contain recognizable link prefixes or a JSON structure. If it is still seemingly random binary data, do not keep decoding it. First check whether the response was compressed, whether the character encoding is correct, and whether any characters were lost during copying.
Step 3: Check line breaks and invisible characters
If the decoded result contains several links but only one node imports, line breaks may not have been recognized correctly. Check whether the links use LF, CRLF, or literal escaped characters. An invisible marker at the start of the file can also prevent the first link prefix from being recognized. During cleanup, remove only confirmed whitespace and markers; do not remove percent-encoding inside a URI.
Step 4: Check protocol fields against client support
If the link is recognized but reports an unsupported parameter, the share format likely contains a field that the current client or core version does not handle. Update to a suitable version of v2rayN, v2rayNG, or v2flyNG, then compare the original configuration's transport, security, and related parameters. Do not delete unknown parameters just to make the import succeed; the removed field may be required by the server.
Step 5: Separate successful parsing from successful connectivity
A node appearing in the list only confirms that text parsing finished. A real connection also depends on server status, DNS resolution, the local network, system time, transport parameters, and the security handshake. First verify that the node fields match the source, then perform an actual connection test. If nodes produced through several conversions all fail, return to the original link or JSON for comparison instead of adding more conversion layers.
Choose the format based on your goal
For regularly fetching multiple nodes, a subscription list is best for centralized updates. To transfer one node between devices, a share link is more direct. To preserve complex traffic splitting, multiple outbounds, local inbounds, and DNS policies, only a complete JSON configuration carries enough information. Choose the format according to the configuration scope, not by which string looks shorter.
For everyday management, use the subscription as the node source and let the client handle updates and grouping, while maintaining routing and DNS locally. When migrating a complex setup, back up the node source and local rules separately instead of treating a single share link as a complete backup. Preserve the source data before conversion, then verify the address, port, UUID, transport, security settings, path, and server name field by field to reduce cases where import succeeds but the connection fails.