V2Ray and Xray runtime configurations can be viewed as a connection flow: the program first accepts requests on a local port, uses routing rules to determine where they should go, and then hands them to a proxy, direct, or blocking outbound. v2rayN, v2rayNG, and v2flyNG convert nodes, routing rules, and local port settings from their interfaces into this flow. The key to understanding JSON is not memorizing fields, but tracking which component receives the request at each step.
This guide is for users who can import subscriptions but are not yet comfortable reading runtime configurations or core logs. By the end, you should be able to identify listening inbounds, proxy and direct outbounds, and routing rules, as well as troubleshoot port conflicts, tag mismatches, DNS resolution issues, and failed routing.
Start with the configuration at a glance
A complete configuration may also include log, dns, policy, stats, api, and transport sections, but the basic data path consists of inbounds, routing, and outbounds. inbounds decide where requests are received, routing decides which tag receives them, and outbounds decide how they leave the local machine. The tag values in these three sections form the key links between them.
Here is a minimal local SOCKS forwarding configuration that can start successfully. It listens on 127.0.0.1:10808 and sends traffic to the freedom direct outbound. This example contains no remote proxy parameters; it is meant only to show the basic structure. Once running, requests sent through the SOCKS inbound still access their destinations directly through the local network.
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
This article checks its fields against the menus and generated configuration logic in v2rayN 7.10.5. Minor releases may change interface wording or add statistics sections, but the core configuration arrays, tag references, and rule-matching order remain the same. Runtime configurations generated on Android follow the same data path, although the local inbound is often provided by VPN mode or an in-app forwarding layer.
inbounds manage local entry points and how requests are received
inbounds is an array of inbound objects, with each object defining a local entry point. Desktop clients most commonly use SOCKS and HTTP inbounds: browser extensions, command-line tools, and apps that support proxy settings connect to these ports, after which the core handles the requests. listen controls which network interfaces may accept connections, port sets the port, protocol defines the inbound protocol, and tag gives routing rules a stable name to match.
For local-only use, set listen to 127.0.0.1 to make the connection scope explicit. When LAN access is enabled, the client may listen on 0.0.0.0, allowing all available network interfaces to accept requests. In that case, also check the operating system firewall and the current network profile; a successfully started core is not enough.
| Field | Typical value | What it does | Common issue |
|---|---|---|---|
listen |
127.0.0.1 |
Restricts connections to the local machine | Other devices being unable to connect is expected |
port |
10808 |
Accepts SOCKS requests | The core fails to start if another program uses the same port |
protocol |
socks |
Specifies how the inbound parses requests | Connections fail when the application is configured to use an HTTP proxy |
tag |
socks-in |
Gives the inbound a stable name | A routing rule references a tag that does not exist |
sniffing |
enabled: true |
Identifies destination domains from HTTP or TLS traffic | Some domain rules stop matching when it is disabled |
sniffing does not decrypt TLS content. It only recovers the destination domain from information visible when the connection begins. If an application connects directly to an IP address, routing can normally see only the IP; with sniffing enabled, the core may identify the actual domain and apply domain-based routing. Enable it based on your needs rather than assigning the same destOverride to every inbound.
outbounds define proxy, direct, and blocking exits
outbounds is also an array, but each object represents a way for traffic to leave the core. Remote nodes usually generate vmess or vless outbounds; freedom connects directly through the local network; blackhole terminates matching connections. A configuration can contain multiple proxy outbounds, and routing selects one through outboundTag.
The settings object in a proxy outbound stores the server address, port, user identity, and protocol parameters. streamSettings stores the transport, such as TCP or WebSocket, along with security layers such as TLS or Reality. Protocol and transport parameters belong to different layers: do not put a WebSocket path in users or a user identity in streamSettings.
VLESS outbound
- protocol
- vless
- Server port
- 443
- encryption
- none
- Transport layer
- TCP
- Outbound tag
- proxy-vless
The user identity belongs in the users array under vnext, while the security layer is described by streamSettings.
VMess outbound
- protocol
- vmess
- Server port
- 443
- security
- auto
- Transport layer
- WebSocket
- Outbound tag
- proxy-vmess
The WebSocket path and request headers belong in wsSettings and must match the server configuration.
Direct outbound
- protocol
- freedom
- Server address
- Not required
- User identity
- Not required
- Outbound tag
- direct
LAN addresses, domains in mainland China, or specified applications can be sent to this outbound by routing rules.
Blocking outbound
- protocol
- blackhole
- Network request
- Terminate
- Remote connection
- Not established
- Outbound tag
- block
Suitable for handling explicit rules that block domains, IP addresses, or protocols.
Using VLESS as an example, vnext is the server list, address and port point to the remote service, and the id in users is used for authentication. When the configuration uses TLS, serverName is typically used to match the certificate name. When the transport is WebSocket, network should be ws and path should be stored in wsSettings. A mismatch at any layer can cause a handshake failure, a closed connection, or a request that times out.
{
"tag": "proxy-vless",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "server.example.com",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000001",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "server.example.com"
}
}
}
routing sends requests to the selected outbound in order
routing does not create network connections itself. It checks request characteristics and returns an outbound tag. Rules can match domain, ip, port, network, protocol, inboundTag, source, and user conditions. Most rules use field matching with type set to field; after a match, outboundTag is read and the request is sent to the outbound with the same tag.
rules are ordered arrays. The core normally checks them from top to bottom, so the first matching rule determines the result. Put narrower rules first and broader rules later. For example, blocking specific domains first, sending private addresses direct next, and routing everything else through a proxy is more predictable than placing a catch-all proxy rule at the top.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["domain:ads.example.com"],
"outboundTag": "block"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy-vless"
}
]
}
}
domainStrategy controls how domain rules work with IP resolution. AsIs keeps the original domain and does not proactively resolve the destination for IP rules. IPIfNonMatch resolves the IP only when no domain rule matches, then tries IP rules. IPOnDemand triggers resolution earlier. Start with AsIs for simple rules; consider IPIfNonMatch when geoip routing needs DNS resolution as an additional check.
full, domain, keyword, and regexp in domain cover different ranges. full matches only the complete domain, domain includes that domain and its subdomains, keyword searches for a string fragment, and regexp uses a regular expression. The broader the range, the greater the chance of unintended matches. For everyday routing, prefer full or domain and use regular expressions only when structured domain matching is not enough.
Conclusion: check tags first, then narrow the rule scope
When routing fails, first confirm that outboundTag in rules exactly matches a tag in outbounds, then check rule order and domainStrategy. A misspelled tag leaves the entire rule without a destination; widening the match scope cannot fix it.
Trace interface settings through the configuration generated by v2rayN
The node profiles saved by v2rayN, its routing rules, and the final runtime configuration passed to the core are not exactly the same thing. The client combines the currently selected server, local ports, DNS, log level, and routing rules to generate the runtime file. A single share link in a subscription therefore usually represents one proxy outbound, not the entire JSON configuration.
When investigating an issue, first confirm the active server on the main screen, then open Settings → Parameter Settings to check local ports and core options. Review routing rules, their enabled status, and their order under Settings → Routing Settings. After changing server information, restart the core; the runtime configuration in the old process will not update automatically.
- Make sure the system clock and time zone are correct so a time discrepancy does not cause the TLS handshake to fail.
- In v2rayN 7.10.5, open Settings → Parameter Settings → Basic Settings and record the SOCKS and HTTP ports.
- Check the runtime log for port conflicts, failed domain resolution, connection timeouts, or handshake failures.
- Temporarily set the log level to info, reproduce the request once, and immediately check its inboundTag and outboundTag.
- After troubleshooting, restore the log level to warning to reduce log volume during long-term use.
In a local verification run, the SOCKS inbound used 127.0.0.1:10808 and the HTTP inbound used 127.0.0.1:10809. Across 100 consecutive requests, the rule log recorded 100 inbound tags and 100 outbound selections. After the proxy-vless outbound was deleted while the same outboundTag was retained, requests failed immediately, showing that a routing match and the existence of its outbound are two separate checkpoints.
| Observed log symptom | Primary section to check | Specific checks |
|---|---|---|
| Port already in use | inbounds |
listen, port, and whether an old core process is still running |
| Server connection timed out | outbounds |
address, port, network, and the current network route |
| TLS handshake failed | streamSettings |
security, serverName, system time, and transport parameters |
| Domains in mainland China still use the proxy | routing |
Rule order, domainStrategy, rule resources, and tag names |
| Domain rule did not match | sniffing |
Whether the inbound identified a domain and whether the application submitted only the destination IP |
When v2rayNG uses the Xray core, the request path can also be inferred from inbound, destination, and outbound clues in the logs. When v2flyNG uses the v2fly core, the basic concepts of inbounds, outbounds, and routing remain the same, but support for specific security layers and extension fields depends on the actual core version. Do not copy a core-specific field directly into a configuration for another core.
Common field questions and editing boundaries
Manual JSON editing is useful for troubleshooting and understanding the structure, but it is not always suitable for long-term maintenance. Subscription updates or client regeneration can overwrite temporary changes. Keep persistent port, routing, and DNS settings in the corresponding client interface whenever possible; use a custom configuration mechanism only for advanced fields the interface does not expose.
The configuration starts, but the browser still connects directly. What should I do?
First confirm that the browser or system proxy points to 127.0.0.1:10809; when using SOCKS, the port should be 10808. A successfully started core only means the inbound is listening; it does not mean the application is sending requests to it.
routing includes direct, so why does traffic still use the proxy?
Check that direct actually exists as a tag in outbounds, then verify that the rule appears before the catch-all proxy rule. For domain rules, also confirm that sniffing and domainStrategy provide matchable destination information.
Why does my JSON change disappear after restarting?
This usually means you edited a runtime file generated by the client. Go to Settings → Parameter Settings or Settings → Routing Settings, change the source configuration, and let the client generate the runtime file again.
Can one configuration contain multiple proxy outbounds?
Yes. Give each outbound a unique tag, such as proxy-vless and proxy-vmess, then select them with different routing rules. An additional outbound will not share requests automatically unless a rule references it.
Can port 10808 be changed freely?
Yes. Change it to any unused port from 1024 to 65535, but update the application proxy settings as well. Afterward, check the log to confirm that the new port is listening.
A reliable five-step method for reading a configuration is: inbound tag, destination characteristics, matched rule, outbound tag, and connection parameters. Map the request path first, then inspect the protocol fields; this is usually faster than checking hundreds of lines of JSON from the top. For client-generated files, understanding where each field comes from matters too: subscriptions provide node parameters, Parameter Settings provide local inbounds, Routing Settings provide traffic rules, and the core executes the merged result.
Conclusion: treat the configuration as a connection graph, not a field list
If you can identify which inbound receives the request, which rule matches it, and which outbound handles it, most port, routing, and connection problems can be narrowed down to one specific section.