This guide is for users who have imported a node and want to understand the configuration used at runtime. Start with the local port to identify the inbound, follow routing tags to find the outbound, then distinguish node parameters from transport settings and client options. You’ll be able to pinpoint which layer is failing and understand why a valid configuration doesn’t necessarily mean a working connection.
1. Client settings vs. runtime configuration
config.json usually refers to the JSON file read by the core; the filename alone doesn’t determine what it contains. v2rayN stores server lists, subscription groups, and UI preferences as client-managed data. When starting the core, the client generates a runtime configuration from the active server and routing settings. Exporting a single share link gives you a node profile, not a complete configuration with inbounds and routing.
Use the actual runtime file as your reference. Export options and generated file locations can vary between v2rayN versions, so make sure you’re exporting the complete configuration rather than a server share link. On Android, v2rayNG uses the Xray core, while v2flyNG uses the V2Fly core. Their basic structures are similar, but that doesn’t mean their extended fields are interchangeable.
inbounds: Accepts connections from apps, such as through a local SOCKS or HTTP proxy port.outbounds: Defines where traffic goes, such as through a VMess proxy, a direct connection, or a blocked connection.routing: Chooses an outbound for each connection based on rules; it does not create the outbound.loganddns: Control logging and the built-in DNS behavior, respectively. Neither is a system proxy switch.
2. A complete config.json sample with sensitive details removed
The sample below follows the structure of a complete client export, with two local inbounds, three outbounds, and two routing rules. The addresses and identity parameters have been replaced with example values. It’s valid JSON, but it won’t connect to a server: example.com:443 doesn’t indicate that a VMess server exists there, so you can’t use this sample to test connectivity.
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": ["localhost"]
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "example.com",
"port": 443,
"users": [
{
"id": "11111111-1111-4111-8111-111111111111",
"alterId": 0,
"security": "auto"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "example.com"
}
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:example.org"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
3. inbounds: listen address, port, and proxy type
The first inbound accepts SOCKS requests at 127.0.0.1:10808; the second accepts HTTP proxy requests at 127.0.0.1:10809. These ports are specific to this sample and may differ from your client’s configuration. Which one an app should use depends on the proxy type you select in the app, not whether the destination website uses HTTP or HTTPS.
SOCKS inbound
- Tag
socks-in- Listen address
127.0.0.1- Port
10808- Protocol
socks
Use this endpoint when the app is set to SOCKS5. UDP also requires support from both the app and the rest of the connection path.
HTTP inbound
- Tag
http-in- Listen address
127.0.0.1- Port
10809- Protocol
http
Use this endpoint when the app is set to use an HTTP proxy. HTTPS destinations typically establish a tunnel with CONNECT.
When listen is set to a loopback address, only local connections are accepted. Changing it to 0.0.0.0 to share the proxy over a LAN exposes it on a wider network. You’ll also need to consider authentication and firewall rules—not just change the address. This sample’s SOCKS inbound uses auth: "noauth", so keep it restricted to local use.
udp: true enables UDP on the SOCKS inbound only. It doesn’t automatically send all system UDP traffic through the proxy, nor does it give the HTTP inbound the same capability. If an app isn’t using this endpoint, you won’t get the expected proxy connection even if the core starts successfully.
4. outbounds: node identity, transport, and outbound tags
outbounds is an array that can contain multiple exits. In this example, the first outbound is tagged proxy and uses VMess. Under vnext, address and port specify the remote server and port; id under users holds the user identity parameter. Here, port 443 is the remote port—it has no relation to the local ports 10808 and 10809.
| Field | Sample value | What to look for |
|---|---|---|
protocol | vmess | Selects the proxy protocol and the structure of its settings. |
users[].security | auto | The encryption option for the VMess user layer; it doesn’t enable TLS. |
users[].alterId | 0 | A common setting for VMess AEAD. It must match the server’s requirements. |
streamSettings.network | tcp | The transport used in this example; supported names and values depend on the core version. |
streamSettings.security | tls | Enables TLS at the transport layer, separate from the user-layer security setting. |
tlsSettings.serverName | example.com | The server name used for TLS and certificate name verification. |
direct uses freedom to connect directly to the destination; block uses blackhole to reject traffic. These are just tag names—the behavior comes from protocol. Renaming the freedom tag to “proxy” won’t turn it into a remote proxy. This sample has no rules that reference block, so declaring that outbound alone won’t block any requests.
Check compatibility: start with the protocol, then check core-specific fields
Don't change the protocol from VMess to VLESS and run the config as-is. They use different identity and encryption fields. For extensions such as REALITY, make sure you're running an Xray core that supports those fields; the filename alone isn't enough to tell.
5. routing: rule order, tag references, and the default outbound
Routing rules are checked from top to bottom. When a rule matches, its outbound is selected. The first rule in this example sends only the exact domain example.org to direct. The full: prefix means an exact match; subdomains aren’t included. The second rule sends destinations matching private address ranges to the same outbound. Connections that match neither rule use the first outbound in outbounds, which is proxy.
- For a connection to the domain
example.org, the first rule matches and selects the outbound withtag: "direct". - For a connection to
192.168.1.20, the second rule matches the private address and connects directly to the LAN destination. - For a connection to any other domain that doesn’t match a rule, the first outbound,
proxy, is used to try to connect to the example VMess server.
outboundTag must exactly match an outbound’s tag, including capitalization. Inbound tags can be used in a rule’s inboundTag array—for example, to match only connections from ["socks-in"]. Inbound and outbound tags aren’t paired automatically and don’t need to have the same name.
This example uses domainStrategy: "AsIs", so routing won’t proactively resolve domains to IP addresses for IP-based rules. If a connection enters routing as a domain, the second rule might not recognize the LAN address it ultimately resolves to. To enable this behavior, first understand when IPIfNonMatch or IPOnDemand performs resolution, then adjust the DNS settings accordingly. Don’t assume every domain request already has a destination IP.
Before changing routing, note the first outbound
Moving direct to the first position in the array changes the default outbound for every connection that doesn’t match a rule. Make changes to rule logic and outbound order separately, one at a time, so you don’t mistake default direct connections for broken rules.
6. dns and log: a successful startup doesn’t guarantee a connection
In this example, dns.servers is set to localhost, allowing built-in DNS to use the system resolver when it needs to resolve a name. This doesn’t open a local DNS server port or automatically intercept requests an app sends to other DNS servers. Routing, outbound, and app-level DNS resolution happen at different points, so consider how traffic enters the core before drawing conclusions.
loglevel: "warning" suppresses routine connection details. For troubleshooting, temporarily switch to info, restart the core, and reproduce the failed request once. Restore the original level when you’re done. Logs may include visited domains, destination addresses, and configuration paths. Remove subscription links, user identity parameters, and personal file paths before sharing logs publicly.
- Core exits immediately: Check the JSON syntax, field types, and protocol options unsupported by the core. The port must be the number
10808, not a string containing explanatory text. - Listen error: Check whether another client instance is already using ports 10808 or 10809. Don’t start by changing the remote server port.
- Local port connects, but the remote connection fails: Check that the server address, port 443, user identity parameter, and TLS server name match the server configuration.
- Only some destinations use the wrong outbound: Check rule order, tag references, whether requests use a domain or an IP address, and which outbound is used when no rule matches.
7. Common config.json questions
The file opens, so why does the core report a configuration error?
Being able to open a file in a text editor doesn’t mean it’s valid JSON. Check for trailing commas, quotation marks, and mismatched brackets, then use the logs to locate the field causing the problem. Even valid JSON must use fields supported by the current core. For example, don’t put an outbound object in the inbounds array.
Why does the connection fail when I enter 10808 as my HTTP proxy port?
In this sample, port 10808 accepts SOCKS requests, while 10809 accepts HTTP proxy requests. Set the app to SOCKS5 and use port 10808, or keep the HTTP proxy type and use port 10809. Before doing so, verify the ports in your own runtime configuration.
Why does traffic still go direct when the config includes proxy?
First, confirm the app is actually connecting to a local inbound. Then check whether a matching rule points to direct. proxy is only a tag; it doesn’t turn on the system proxy. Check the client’s system proxy setting and the core’s routing configuration separately.
Can I import my full desktop configuration into an Android client?
First, check which core fields and import methods the target client supports. Desktop listener ports, log paths, and routing data may not suit Android. If you only need to sync servers, import a subscription or node share instead, then configure local listeners and routing in the target client. Don’t overwrite its entire runtime configuration.