V2Ray Configuration File Explained: inbounds, outbounds, and routing

Using a minimal working config.json, this guide explains inbounds, outbounds, and routing field by field, so you can edit V2Ray configurations with confidence.

At a glance

This guide is for users who can import nodes but still are not sure how requests move through config.json. Starting with the local 10808 port, it breaks down inbounds, outbounds, routing, DNS, and logs, then provides a syntax-checkable V2Ray 5 configuration skeleton. You will learn to spot port conflicts, incorrect outbound tags, and misordered rules.

Follow the data flow: how the configuration works together

A V2Ray configuration is not a collection of independent switches. An application first hands a request to an inbound. The routing module reads the destination domain, IP, port, and inbound tag, then sends the request to the selected outbound. If no routing rule matches, V2Ray normally uses the first item in the outbounds array, so the order of outbounds matters too.

inbounds answer “where does traffic enter?”, outbounds answer “where does it leave?”, and routing connects the two. A configuration starting successfully only proves that its JSON structure and fields are broadly parseable. To confirm traffic is split as intended, also check tag references, rule order, and DNS results.

Application sends a requestInbound port receives itRouting rule matchesOutbound tag is selectedDestination server
10808
Example SOCKS inbound port
10809
Optional HTTP inbound port
3 types
Proxy, direct, and blocked outbounds
Top to bottom
Routing rule order

Minimal configuration skeleton: start with complete JSON

The example uses a local SOCKS inbound, a VMess proxy outbound, a direct outbound, and a blocked outbound. The server domain, port, user ID, and transport are structural examples only; in real use, each must match the server-side parameters. JSON does not allow comments, so explanatory text must not be placed in a production configuration file.

{
  "log": {
    "loglevel": "warning"
  },
  "dns": {
    "servers": [
      "1.1.1.1",
      "localhost"
    ]
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-3333-4444-555555555555",
                "security": "auto"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "none"
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "block",
      "protocol": "blackhole"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "protocol": [
          "bittorrent"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "geosite:cn"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": [
          "geoip:cn"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

This configuration sends requests that match no rule to the first outbound, proxy. Private addresses, domains in mainland China, and IP addresses in mainland China go to direct, while selected protocols go to block. If direct is moved to the first outbound without adding an explicit proxy rule, unmatched traffic will become direct.

inbounds: how applications hand traffic to the core

An inbound is the receiving endpoint V2Ray opens locally. The example listens on 127.0.0.1:10808 using SOCKS. Once a browser, download tool, or system proxy points its SOCKS address to this port, requests can enter V2Ray. Starting the core without directing applications to the inbound port will not automatically capture ordinary application traffic.

settings.auth set to noauth means this SOCKS endpoint requires no username or password, so it should remain bound to the local machine. udp: true allows SOCKS UDP requests to enter, but the outbound protocol, server, and network must also support them. Enabling this field alone does not guarantee that all UDP traffic will work.

SOCKS inbound

Listen address
127.0.0.1
Listen port
10808
Protocol
socks
UDP
true

Suitable for browsers, command-line tools, and desktop applications that support SOCKS5 settings.

HTTP inbound

Listen address
127.0.0.1
Suggested example port
10809
Protocol
http
Purpose
HTTP proxy endpoint

When both endpoint types are needed, use different ports to avoid a listen conflict.

Multiple inbounds can run at the same time. For example, keep 10808 for SOCKS and add 10809 for HTTP. Give each inbound a distinct tag so routing rules can distinguish their sources with inboundTag. To change v2rayN’s local ports, open “Settings” → “Parameter Settings” and check the SOCKS and HTTP ports; the proxy ports in the application must be updated as well.

outbounds: the roles of proxy, direct, and block

An outbound defines how a request leaves V2Ray. A proxy outbound usually contains the server address, server port, user credentials, and transport settings; a direct outbound uses freedom; and a blocked outbound uses blackhole. The routing module does not establish remote connections itself; it selects an outbound tag according to the rules.

In the VMess example, vnext is a list of servers, and each server can contain a set of users. address and port must match the server’s listening details, while id must be a user identifier accepted by the server. Also verify the transport layer, including TCP, WebSocket, and TLS. A single mismatch between client and server can cause an immediate disconnect after connection or repeated timeouts.

Proxy outbound proxy

Protocol
vmess
Server port
443
Example transport
TCP
Default purpose
Unmatched traffic

Use parameters from a valid node configuration for the real server; do not replace only the address while retaining the other example values.

Local policy outbound

direct
freedom
block
blackhole
Connect to a server
Not required
Selection method
routing tag

Direct and blocked handlers are outbounds too, and each needs a unique tag for rules to reference.

Field Location Purpose Common mistake
protocol Outbound object Determines the outbound handler type Putting VMess parameters in a VLESS outbound
settings Outbound object Stores server and user parameters Port, user ID, or server settings do not match
streamSettings Outbound object Defines the underlying transport and security layer TCP, WebSocket, or TLS settings do not match
tag Outbound object Referenced by routing rules A rule references a nonexistent tag

Bottom line: verify the outbound first, then tune routing

Temporarily keep only one proxy outbound and test the connection. After confirming that the server parameters work, add direct, block, and routing. Otherwise, node and traffic-splitting errors appear together, making the logs difficult to interpret.

routing: rule order determines the final exit

routing.rules is an array checked from top to bottom. Once a request matches a rule, V2Ray uses that rule’s outboundTag and stops processing later rules for that request. Put narrower, higher-priority rules first and broader rules later.

domainStrategy: IPIfNonMatch first tries domain-based rules. If no domain rule matches, it resolves the IP and continues checking IP rules. This allows geosite:cn and geoip:cn to work together, but it also means DNS results affect IP-rule decisions.

  1. Handle protocols or destinations that must be blocked first, so a broad direct rule later cannot take over too early.
  2. Next, process geoip:private so local-network and private addresses connect directly.
  3. Then match geosite:cn and choose a direct connection for domains in that category.
  4. If the domain does not match, use geoip:cn to check the resolved destination IP.
  5. Remaining traffic falls through to the first outbound, proxy, when no rule matches.
Match condition Example value Target outbound Result
protocol bittorrent block Sent to the blocked outbound
ip geoip:private direct Local-network and private addresses connect directly
domain geosite:cn direct Connect directly after matching a domain in the category
ip geoip:cn direct Connect directly after matching the destination IP

The outboundTag in a rule is not a protocol name; it is the tag of an outbound object. If the outbound tag is proxy but the rule says Proxy, they are not the same tag. When deleting or renaming an outbound, search the entire file and update every reference.

Bottom line: move only one routing rule at a time

Record the destination domain and expected exit first, then move one rule and watch the logs. Copying in an entire new rule set changes domain rules, IP rules, and the default exit at once, making it difficult to identify the cause of a problem.

DNS and logs: why traffic can split incorrectly even when the configuration is valid

DNS does more than translate domains into IP addresses. When domain and IP matching are combined, resolution results participate in routing decisions. The example places 1.1.1.1 and localhost in the server list, allowing either a specified DNS server or the local resolver; on a real network, choose based on reachability, resolution results, and routing goals.

Set loglevel to warning for everyday use to see warnings and errors. Temporarily switch to info when troubleshooting rules for more complete runtime details, then switch back after confirming the issue to prevent rapid log growth. JSON strings must use double quotes, and the final array item or object field must not have a trailing comma.

{
  "log": {
    "access": "access.log",
    "error": "error.log",
    "loglevel": "info"
  },
  "dns": {
    "hosts": {
      "domain:internal.example.com": "192.168.1.20"
    },
    "servers": [
      "1.1.1.1",
      "localhost"
    ]
  }
}

Common editing problems: infer the field from the error

Manual edits usually cause three types of problems: broken JSON syntax, fields placed at the wrong level, and broken tag references. Syntax errors usually prevent the core from starting; misplaced fields may trigger an unknown-field error; tag errors may appear only when a request actually matches the rule. Validate the file first, then check the entry point, and finally trace the request path.

The browser stopped connecting right after changing the port. What should I do?

Check inbounds.port in config.json and the browser’s proxy port together. For example, if the inbound changes from 10808 to 10818 while the browser still points to 10808, requests cannot reach the new endpoint.

The configuration test passes, so why is all traffic going direct?

Check whether the first item in outbounds has become direct. Unmatched requests use the default outbound. If the default should be a proxy, place a working proxy outbound first or add an explicit proxy rule for the target.

Why is traffic still not split by domain after adding geosite rules?

First confirm that the rule appears before broader IP rules, then check domainStrategy. If the application submits only the destination IP and not the domain, domain rules cannot access the original domain information.

The logs say the proxy outbound cannot be found. What should I do?

Search for tag inside outbounds and confirm that an object has the value proxy. Tags are case-sensitive, and no spaces may be added before or after the tag.

After importing a node into v2rayN, do I still need to write the entire JSON by hand?

Usually not. v2rayN generates the runtime configuration from the node and parameter settings. To customize local ports, open “Settings” → “Parameter Settings”. Manual JSON maintenance is generally needed only for custom configurations, complex inbounds, or specialized routing.

For v2rayNG and v2flyNG, subscriptions or share links likewise generate the configuration required by the client. v2rayNG uses the Xray core, while v2flyNG uses the v2fly core, so field names and supported transports may differ by core. Do not overwrite one core’s environment with a complete configuration exported by another without first checking protocol, transport fields, and routing resources for compatibility.

  1. Back up the working config.json and record the local inbound port.
  2. Change one section at a time, and run a configuration test after saving.
  3. Start the core and confirm that 127.0.0.1:10808 is listening successfully.
  4. Test the proxy outbound with a single destination, then test direct and blocked rules.
  5. Watch the destination address, match result, and connection errors in the logs before making the next change.
Download V2Ray clients Windows, macOS, Android, Linux