Browse the complete guide

V2Ray Beginner to Advanced Complete Configuration Guide

Work through the guide chapter by chapter, covering core concepts, client installation, subscription management, proxy modes, split routing, TUN, troubleshooting, maintenance, and configuration structure. For a first setup, read the chapters in order; when checking a specific parameter, use the contents to jump directly to it.

v2rayN · Desktop v2rayNG · Android v2flyNG · Android VMess · VLESS · Routing

How to use this guide

Quick-start guide → takes you through the shortest path to a working setup. It is ideal if you already have a subscription URL and want to import it and connect quickly. This page explains why each setting is used, where the different modes differ, and which layer to check when something goes wrong. The two guides complement each other, so you do not need to read both from the beginning.

If you have not chosen a client yet, start with the platform selection in Chapter 2. If installation is complete but connections fail, jump to Chapter 7. Before editing routing rules or reading the underlying JSON, understand the relationship between inbounds, outbounds, and routing in Chapter 1, then continue with Chapters 5 and 8.

01
Build the mental model

Core concepts: Clients, cores, and traffic paths

Separate the graphical client from the proxy core

v2rayN, v2rayNG, and v2flyNG are graphical clients for different platforms. They store subscriptions, display nodes, generate runtime configurations, change system proxy settings, and provide visible controls for starting and stopping services. The client’s core is what actually handles connections, protocols, transports, and routing. v2rayN can manage the relevant cores on desktop systems; v2rayNG primarily runs on the Xray core; and v2flyNG corresponds to the V2Fly core. When troubleshooting, identify whether the problem is in the interface layer, the system proxy layer, or the core. A status showing that the client has started only proves that the process is running; it does not, by itself, prove that the target application’s traffic has entered the local proxy.

Project V is a technical ecosystem of related protocols, tools, and implementations, while V2Fly and Xray are two commonly used core families within it. For most users, the practical differences between cores concern protocol support, configuration fields, and transport combinations. You do not need to study every low-level field before choosing a client, but the node protocol in a subscription must be recognized by the active core. For example, when a node combines VLESS with REALITY, both the client and core must support the relevant fields. A successful subscription update alone does not mean that the node parameters will run correctly.

Understand a request through inbounds, outbounds, and routing

A V2Ray configuration can first be reduced to three parts. An inbound receives traffic from local applications, commonly through a local SOCKS or HTTP port, or through virtual network traffic captured by TUN. An outbound determines where the traffic goes next, usually including a proxy outbound, a direct outbound, and a blocking outbound. Routing sits between them and selects an outbound according to conditions such as domain, IP, port, network type, or process. Once this path is clear, many interface options stop looking isolated: the system proxy tells applications which inbound to use, node selection determines the proxy outbound’s parameters, and split-routing rules send different requests to different outbounds.

Application request Local inbound Route match Proxy or direct outbound

Consider a browser visiting a website. The browser first sends the request to the client’s local listening port according to the system proxy settings. After obtaining the target domain, the core checks routing rules from top to bottom. A proxy match sends the request through the selected node; a direct match creates the connection through the local network. The path changes if the browser does not read the system proxy, the application uses its own networking stack, or the address is resolved incorrectly before routing evaluates it. Therefore, “client running,” “system proxy enabled,” and “application traffic captured” are three separate states to verify.

Nodes, share links, and subscriptions are different objects

A node is a set of parameters capable of establishing a connection, typically including a server address, port, user identifier, protocol, transport, TLS options, and server name. A share link is a serialized representation of one node, such as text beginning with vmess:// or vless://. A subscription URL retrieves a collection of nodes or grouped settings and can be refreshed later. A subscription is not the proxy server itself; it is closer to a refreshable list. Deleting a local subscription does not change the remote content, and edits made to a generated node may be overwritten at the next update.

Protocols and transports should also be understood as separate layers. VMess and VLESS describe connection protocols; TCP, WebSocket, and gRPC describe the carrier transport; TLS and REALITY provide specific security and handshake combinations. Every field must match the server configuration, so repeatedly switching local options is not a reliable diagnostic method. For terminology, see the glossary →. Establishing this structure before installation and configuration helps keep “subscription update failed,” “node handshake failed,” and “system did not capture traffic” as separate problem categories.

02
Prepare the environment

Choose a client and complete installation

Choose a client based on the platform and core requirements

For desktop systems, v2rayN is the primary choice, covering Windows, macOS, and Linux and suited to users who need subscription management, system proxy settings, routing rules, and TUN. On Android, choose v2rayNG or v2flyNG: v2rayNG uses the Xray core and is a good fit when a subscription contains newer Xray protocol combinations; v2flyNG uses the V2Fly core and suits configurations built around the V2Fly ecosystem. Installation links, architecture details, and package types for all three clients are collected on the download page →. Do not identify a platform from similar words in a filename alone.

Platform Recommended client Check before installing Primary use
Windows v2rayN System architecture, desktop build, or classic WPF build System proxy, routing, TUN, and subscription management
macOS v2rayN Apple Silicon or Intel processor Desktop proxy and subscription management
Android v2rayNG / v2flyNG Confirm the arm64 or universal package first Capturing application traffic on mobile and Wi-Fi networks
Linux v2rayN Distribution package format and x64 or arm64 architecture Desktop proxy, TUN, and configuration management

Installation considerations for Windows, macOS, and Linux

Windows users should first choose between the desktop build and the classic WPF build. The desktop build uses a cross-platform interface and suits users who want a consistent workflow across desktop systems; the classic WPF build suits users accustomed to the traditional Windows interface and established configuration flow. Neither should control the system proxy at the same time as the other. Before switching versions, exit the running client and record the subscription URL, routing configuration, and custom ports. If an old process remains in the system tray, exit it normally instead of deleting the program directory it is using.

On macOS, processor architecture is the key installation consideration. Choose the arm64 package for Apple Silicon devices and the x64 package for Intel devices. Check the chip type in System Information. On first launch, the system may ask you to approve permission for the app to run; enabling the system proxy or TUN may also require authorization to change network settings. This authorization is used to write the relevant system network settings, and canceling it will usually prevent the mode from being fully enabled. If the app is moved to another directory, the system’s record of its path may change, so place it permanently before configuring launch at login.

Linux users should choose a deb or rpm package based on the distribution, then confirm the processor architecture. Debian, Ubuntu, and derivatives generally use deb; Fedora, Rocky Linux, and other common rpm-based distributions use rpm. Desktop environments expose different system proxy interfaces. After the client writes the settings, verify in the desktop network panel that the HTTP, HTTPS, or SOCKS proxy points to the local listening address. Programs run only in a terminal usually do not read the desktop proxy automatically and may require explicit environment variables or TUN.

Android installation and background-running requirements

Most current Android devices use arm64; when the architecture is uncertain, choose the universal package. After installation, the first connection triggers the system’s network connection authorization, a standard step required to create local traffic capture. v2rayNG and v2flyNG should not stay connected at the same time, because the client started later will take over the system-provided capture channel. Before switching clients, disconnect the current one, then import the same subscription to compare compatibility.

Mobile operating systems may restrict background processes after the screen turns off. If the connection drops after the device has been locked for a while, check the client’s battery policy, background activity permission, and power-saving rules before changing node parameters. Switching between mobile data and Wi-Fi can invalidate existing connections, requiring the core to establish a new outbound; a brief interruption at that point is a network change, while persistent failure warrants checking the logs. Pinning the client in recent tasks or allowing background activity can reduce interruptions caused by system cleanup.

Run a minimal check after installation

After installation, start the client but leave TUN, complex routing, and custom DNS disabled for now. Confirm that the interface opens normally, the core starts, the log directory is writable, and note the default local port. Then import one known-good subscription or node and make the first connection through the system proxy. A minimal setup establishes a baseline: if it works, later problems usually come from newly added routing, DNS, or TUN options; if it already fails, check the subscription, node parameters, and local port conflicts first.

03
Build the configuration

Import subscriptions, choose nodes, and update

Check the boundaries of a subscription URL before importing

A subscription URL is usually an HTTPS address that the client uses to retrieve a node list. Preserve the complete path and query parameters when copying it; do not copy only the domain, and do not confuse a page URL with the subscription endpoint. Remove any leading or trailing spaces and line breaks before saving. Treat a subscription as sensitive configuration access: do not include it in public screenshots, log posts, or shared documents that others can read. If the provider changes the URL, update the subscription entry in the client instead of continuing to edit nodes generated from the old URL.

In v2rayN, open subscription group management, add a subscription name and URL, save it, and run an update. In v2rayNG or v2flyNG, add an entry through subscription settings, then return to the main screen and refresh. The name is only for local identification, so use a purpose or environment name. After import, you should see node entries, not just a subscription group. If the update reports success but the list is empty, check whether the response is actually in a format the client can recognize and whether the current group filter is hiding the new entries.

What a subscription update can overwrite

Subscription nodes are generated from a remote list, so a later update may replace the server, port, protocol, and transport parameters of the same node. Editing a subscription node directly is useful for temporary diagnosis, but not as a long-term customization method. To preserve a custom node, create a separate manual group or copy it as a local node with a clear name. Routing rules, system proxy mode, and local listening ports are usually client settings and are not automatically replaced by subscription updates. Some subscriptions can include group or rule information, however, so use the import preview as the final reference.

A sensible update flow is to stop important active connections, run the subscription update, review additions, removals, and name changes, then test one node. Do not change DNS, routing, and proxy mode at the same time, or it will be difficult to identify the cause of a failure. If an old node disappears, first confirm that the subscription list has changed. If the node remains but fails to connect, check whether its protocol fields changed and whether the core supports them.

Do not rely on a single test when choosing a node

Connectivity checks, latency tests, and real connection tests offered by clients do not target exactly the same thing. A reachable TCP port only shows that the network can reach that port; a successful protocol handshake provides stronger evidence that the key parameters match; and access to a target website also depends on DNS, routing, and the target service. One test result therefore cannot replace full access verification. A safer method is to select a node, enable the system proxy, visit a known-working HTTPS page, and check the client log for the corresponding connection.

Node names can help identify a purpose, but they are not proof of protocol details. Confirm the address, port, protocol type, transport, TLS setting, serverName, and related identifiers in the node details. If a subscription contains several protocol combinations, prefer nodes explicitly supported by the active core. v2rayNG and v2flyNG may show different entries from the same subscription, usually because of core support or subscription conversion results; this does not necessarily mean that the subscription URL is invalid.

Import share links and JSON manually

A single-node share link is useful for temporary import or isolated testing. Before importing, check that its prefix is a protocol supported by the client, then use an entry such as “Import from clipboard.” When copying multiple links, make sure each line contains exactly one complete link. A JSON configuration contains more complete inbound, outbound, routing, and DNS information and generally should not be mixed directly with a configuration generated automatically by the graphical client. If the client offers a custom configuration feature, run it as a separate configuration item so automatic node settings do not overwrite its fields.

{
  "address": "server.example.com",
  "port": 443,
  "id": "11111111-2222-3333-4444-555555555555",
  "security": "auto",
  "network": "tcp",
  "tls": "tls",
  "serverName": "service.example.com"
}

The fields above only illustrate the relationship between node parameters; they do not describe a connectable service. In a real configuration, the address, port, user identifier, transport, and server name must match the server. When a handshake error occurs, check each field instead of randomly changing encryption or TLS options. To understand the difference between share links and subscriptions, read VMess links vs. subscription URLs →.

04
Capture traffic

System proxy, local ports, and application boundaries

The system proxy changes the application entry point

System proxy mode points the operating system’s proxy address to the client’s local listening port. Browsers and desktop applications that support system proxy settings then send requests to that port, where the core handles routing and outbound connections. It does not rewrite every network packet, nor can it guarantee that every program follows the system setting. Some command-line tools, games, virtual machines, containers, and programs with their own networking stacks may ignore it. When a browser works but another program does not, first check whether that program supports HTTP or SOCKS proxies instead of suspecting the node.

Client interfaces commonly offer states such as “Clear system proxy,” “Set system proxy,” and “Do not change system proxy.” Setting the system proxy suits ordinary desktop applications; clearing it restores the system network state when you exit; leaving it unchanged starts only the local port, allowing each application to be configured manually. Exit the client normally so it can restore the previous setting. If the process is force-terminated, the system may retain a proxy address pointing to the local port, leaving websites inaccessible after the client closes. Reopen the client and clear the system proxy, or restore it manually in the system network settings.

HTTP, SOCKS, and mixed ports

An HTTP proxy suits browsers and applications that support CONNECT. A SOCKS proxy can carry more general TCP requests and, depending on the application, can handle domain resolution. Some clients provide a mixed port that recognizes both HTTP and SOCKS requests on one listening address. The port number itself has no protocol capability; what matters is the inbound type assigned to it. When configuring an application manually, its proxy type must match the client’s listening type. Putting a SOCKS port into a field that accepts only HTTP proxies will usually fail immediately.

Capture method Suitable for Verify Common limitation
System proxy Browsers and ordinary desktop applications System proxy address and local port Applications may ignore system settings
Per-application proxy Programs that support a separately configured proxy Matching HTTP or SOCKS type Each application must be configured separately
Environment variables Some command-line tools Whether the current terminal session inherits them Different tools follow different rules
TUN Applications that do not read the system proxy Routing table, DNS, and permissions Higher configuration complexity

Verify proxy variables explicitly for command-line tools

On Linux, macOS, and Windows terminals, many tools do not automatically read the desktop proxy settings. You can set proxy environment variables for a single command or the current terminal session. The examples below assume the client’s HTTP inbound listens on local port 10809; in practice, use the value shown in the client interface. Variable names differ in capitalization and tool support, so use the tool’s verbose output to confirm that the setting was applied.

export http_proxy="http://127.0.0.1:10809"
export https_proxy="http://127.0.0.1:10809"

curl -I https://example.com

unset http_proxy
unset https_proxy

If you use a SOCKS inbound, some tools support socks5h://127.0.0.1:10808. The h form generally means that domain resolution also goes through the proxy, helping avoid a mismatch between local DNS results and the intended routing. Not every program recognizes this syntax, so check the program’s own options. Do not write the variables permanently into a global startup file until you have confirmed that the port starts reliably with the client; otherwise, every terminal program inheriting them will continue trying to connect to a local service that no longer exists.

Confirm that the local port is actually listening

When an application reports “connection refused,” check the local inbound before the remote server. On Windows, use PowerShell to inspect listening sockets; on Linux, use ss. If the port is not listening, the core may not have started, configuration generation may have failed, another process may own the port, or a security policy may be blocking the bind. If the port is listening normally but there are no access logs, application traffic has not reached that inbound. Only when inbound records appear alongside a remote handshake error should you investigate node parameters.

Get-NetTCPConnection -State Listen |
  Where-Object LocalPort -In 10808,10809

ss -lntp | grep -E '10808|10809'

When running multiple clients, do not assign them the same local port or let two clients write the system proxy at once. Give a second test client a different port and keep the system proxy pointed at the one currently being verified. After comparing them, remove unused listening settings to prevent port conflicts at startup. The goal of proxy mode is a clear, observable traffic entry point, not every switch enabled simultaneously.

05
Control the exit path

Split routing rules and match order

Routing rules select an outbound

Routing does not change the node protocol; it only decides which outbound handles a category of traffic. Common outbound tags include proxy, direct, and block, representing proxying, direct connection, and blocking. Rules can match domains, IPs, ports, network types, and inbound tags. Interface labels such as “Global,” “Bypass LAN,” and “Rule mode” package groups of routing behaviors; the actual result still depends on rule order, conditions, and the final default outbound in the generated configuration.

When creating rules, start with narrow rules whose targets are clear, then handle broad collections, and keep a default destination at the end. Local and private-network addresses should usually go direct first; domains that must be blocked should come before general proxy rules; remaining requests can then go to the proxy or direct default. A broad rule at the top prevents later specific rules from running. When a rule appears ineffective, the first check is whether an earlier rule already matched it.

Domain and IP rules are evaluated at different stages

Domain rules match the domain in the request and can use an exact domain, a subdomain suffix, a keyword, or a geosite category. IP rules match the destination IP and can use CIDR ranges or a geoip category. Whether a request contains both domain and IP information depends on the inbound protocol, DNS policy, and whether domain resolution takes place. If you rely only on IP rules, the core may need to resolve the domain first; if that resolution follows the wrong outbound, it can create a loop or an incorrect result. Prefer domain rules for services that can be expressed reliably by name, and reserve IP rules for address ranges.

domain: usually denotes an exact domain, full: emphasizes a complete match, and keyword: matches domains containing the specified text and is therefore broad. geosite: and geoip: reference categorized data sets and are useful for managing large rule collections, but the data must be updated with the client’s resources. Give custom rules explanatory names and document them externally so their source and purpose remain clear months later.

Structure of a minimal routing configuration

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "domain:intranet.example.com"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": [
          "domain:service.example.net"
        ],
        "outboundTag": "proxy"
      }
    ]
  }
}

domainStrategy determines whether and when to resolve an IP when domain rules do not produce a direct result. AsIs favors matching the original domain and does not actively resolve it for IP rules; IPIfNonMatch resolves the IP after domain rules miss, then continues checking IP conditions. Some cores also offer more aggressive strategies. Choose with the DNS configuration and routing goals in mind, rather than assuming that “more resolution” is always more accurate. If the existing domain rules are complete, keep the strategy simple; introduce additional resolution only when routing by destination range requires it.

Expand gradually from simple rules

For a first split-routing setup, keep only three layers: direct access for private networks, explicit domain rules, and a default outbound for everything else. Once it is stable, add ad blocking, process-specific, port, or protocol rules. Adding a large set of unknown rules at once makes errors difficult to locate and may send software updates, local-device discovery, or DNS requests to the wrong outbound. After each addition, test at least one destination that should go direct and one that should use the proxy, and confirm the final outbound tag in the log.

Port rules work well when the destination port clearly identifies a protocol, but modern services often share port 443, so port alone cannot distinguish sites. Process rules depend on the platform and capture method and may not provide complete process information in system proxy mode; TUN support also varies by client implementation. Do not copy a process rule that works on one platform directly to every device. When syncing across platforms, prioritize domain and IP rules, then maintain process conditions separately for each platform.

Troubleshoot routing by checking the final match

When a website uses the wrong outbound, record its domain first, then find the corresponding connection’s outbound tag in the log. If the log shows only an IP, check whether DNS and sniffing settings preserve the domain. Then evaluate the rules from the top, one by one, to see whether the domain or IP could have matched earlier. Temporarily placing the target domain in a clear first rule can confirm a priority problem; after testing, move it to a sensible position instead of relying on a permanent top-of-list exception.

For practical split-routing patterns that use direct connections in mainland China and proxy connections for destinations outside mainland China, read split-routing rules in practice →. Also confirm that rule data and client resources are available before configuring. Routing is a deterministic matching process: retaining the target, matched rule, and outbound tag provides enough evidence to locate the problem layer by layer, without repeatedly switching nodes and guessing.

06
Cover more applications

TUN mode, DNS, and routing-table coordination

TUN covers traffic that system proxy settings miss

TUN mode receives system traffic through a virtual network interface, then passes it to the core for routing and forwarding. It suits applications that do not read system proxy settings, some command-line programs, and desktop environments that need unified capture. Compared with a system proxy, TUN operates closer to the network layer, so more variables matter: the virtual interface address, system routes, DNS capture, MTU, bypass addresses, and permissions can all affect the result. Before using TUN for the first time, verify that the same node connects successfully in ordinary system proxy mode, separating node issues from TUN issues.

Enabling TUN usually requires system network-management permission to create a virtual interface and write routes. A normal client exit should remove these temporary settings; an abnormal termination may leave an old interface or route behind. If the network remains broken after closing the client, restart it, disable TUN normally, and then inspect the system interfaces and default route. Do not run multiple tools that modify virtual adapters or routing tables at the same time, or the same destination range may be repeatedly overwritten by conflicting rules.

DNS determines what routing can see

When an application accesses a domain, it must first obtain a resolution result. If DNS requests bypass the client, the core may see only the IP of the subsequent connection. If TUN captures DNS, the core can use domain rules to choose the resolver and outbound. The goal is not to send every query through one path, but to keep resolution results, routing decisions, and actual connections consistent. For example, an internal domain intended for direct access should use a DNS server that can resolve that internal zone; a request routed by domain should ensure that the core still has the original domain for matching.

Common failures include a successful resolution that returns an unreachable address, DNS requests routed back into the local inbound and creating a loop, stale application results, IPv6 being preferred when the current path does not support it, and a browser bypassing the system setup through its own DNS configuration. Start by clearing application and system DNS caches, then check whether the client log contains query records. If the target IP responds directly but the domain fails, focus on DNS; if the domain resolves and the connection fails during the handshake, return to the node and transport parameters.

When to use Fake DNS versus real resolution

Some TUN configurations use Fake DNS: the core first returns a reserved address to the application, then restores the original domain through a mapping and applies routing. This preserves domain information and can reduce cases where applications bypass domain rules. It requires the traffic to stay within the same core and mapping, however. If an application caches the reserved address and continues using it after the client stops, the request will fail. LAN services, programs that require real IPs, and some peer-to-peer scenarios should usually be excluded rather than universally sent through Fake DNS.

Enable it only when the actual requirement calls for it. If ordinary browsers and system-proxy-aware applications already work reliably, there is no need to enable it merely for a “more complete” configuration. When a specific application does not follow the system proxy, start with a real-DNS TUN configuration, verify routing and MTU, and then consider Fake DNS. For every added processing layer, preserve a comparison result with that layer disabled.

MTU, IPv6, and LAN bypass

MTU controls the size of an individual packet carried by the virtual interface. A value that is too high can cause fragmentation or packet loss on some network paths, appearing as small pages that open while larger responses stall; a value that is too low adds overhead. Without a clear symptom, keep the client default. If TLS handshakes stall or uploads fail only on a particular network, lower MTU gradually for comparison, rebuilding the TUN interface and recording the result after each change. Avoid changing several network parameters at once.

IPv6 must be considered across four layers: the system, DNS, the node, and the outbound path. A device having an IPv6 address does not mean that the proxy outbound supports IPv6; once DNS returns an AAAA record, the application may prefer IPv6. If the current configuration lacks complete IPv6 routing, follow the strategy provided by the client instead of leaving IPv6 half-enabled and half-blocked between the system and client. LAN ranges should normally bypass the proxy directly so printers, router admin pages, file shares, and local development services are not sent to a remote outbound.

{
  "routing": {
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "port": "53",
        "network": "udp",
        "outboundTag": "dns-out"
      }
    ]
  }
}

The example expresses a routing relationship: private addresses go direct first, while qualifying DNS traffic goes to a dedicated outbound. In a real configuration, you must also define an outbound named dns-out, or the rule reference will fail. A graphical client may generate this structure automatically, so do not overwrite the complete configuration without understanding how it is built. For customization, export the current running configuration first, confirm the inbound and outbound tags, and then add the smallest necessary rule.

Enable TUN in four steps

First, verify the node and subscription in system proxy mode. Second, close other programs that write network routes. Third, enable TUN while keeping the default DNS and MTU, then test a browser, command-line tools, and LAN addresses. Fourth, use the logs to add DNS split routing or bypass rules if needed. If a step fails, return to the previous one for confirmation; do not enable Fake DNS, change MTU, switch IPv6, and import a large routing set simultaneously. A stable TUN configuration comes from layered verification, not the number of enabled switches.

07
Keep it working

Routine maintenance, log reading, and troubleshooting

Treat client, core, subscription, and rule-data updates separately

Routine maintenance does not mean reinstalling the client repeatedly. At minimum, track four categories: the graphical client handles the interface and configuration generation; the core runs the protocols; the subscription supplies node parameters; and rule data supplies geosite and geoip categories. They update on different schedules and may be managed separately by the client. When a problem appears, record which layer changed most recently. A strange interface after a client update is different from one node failing after a subscription update; stale rule data is more likely to cause category mismatches than to prevent every node from starting.

Before updating, preserve the subscription name, custom routes, local ports, and key screenshots. Afterward, first test the existing node with a simple system proxy, then restore TUN or complex rules. Do not combine a client update, subscription refresh, and major routing change in one operation. If you need to roll back, revert the most recent change first and confirm that the configuration directory remains compatible. Users who launch at startup should also verify that the startup path did not change and that no old process remains in the system tray.

Read logs by time and connection stage

Useful logs usually cover configuration loading, inbound listening, DNS queries, routing results, outbound dialing, and protocol handshakes. Before troubleshooting, clear old logs or note the current time, then perform the target action once. Large volumes of history can hide the actual error. When you see connection refused, determine whether the refusal came from the local port or remote address; for a timeout, identify whether it occurred during DNS, TCP connection setup, or the protocol handshake; a configuration-field error means the core never reached the network stage.

Raise the log level temporarily when you need more detail, but leaving it high produces large files and may record runtime information such as visited domains. Restore the normal level after troubleshooting. Before sharing logs, remove subscription URLs, server addresses, user identifiers, authentication fields, and local paths, keeping only the error type, stage, and necessary context. Do not share only the final line; the real cause may be in earlier configuration-loading or DNS records.

Choose a troubleshooting branch by symptom

Symptom Check first Next step
Core will not start Configuration syntax, port conflicts, and file permissions Read the first error during startup
No browser access records System proxy and local listening port Confirm that the application reads system settings
Every node times out Local network, DNS, and system time Switch capture methods and check the public network
Only one node fails Node parameters and protocol support Update the subscription and verify transport fields
LAN stops working after TUN is enabled Private-range bypass and system routes Add an explicit direct rule
Domain fails but IP is reachable DNS path and cache Check query logs and returned records

System time, port conflicts, and permissions are common baseline issues

TLS and REALITY handshakes depend on a reasonable system clock. A significant device time offset can cause certificate-time or handshake errors. Enable system time synchronization and confirm the time zone is correct. Port conflicts commonly occur when an old client, a test build, or another local proxy is running at the same time. Use system commands to identify the listening process instead of repeatedly trying random ports. If you change the port, update the system proxy, manually configured application proxies, and environment variables as well.

Permission issues mainly affect TUN, system proxy writes, configuration directories, and log directories. Ordinary system proxy use usually does not require running with elevated privileges long term; creating a TUN interface may require system authorization. If the program starts only with elevated privileges, identify the specific failed file or network operation instead of treating permanent elevation as the default fix. If the configuration directory is not writable, the client may open normally but fail to save subscriptions and rules, causing all changes to disappear on exit.

Restore network access by removing capture first, then troubleshoot the node

If the entire system loses network access after a client failure, restore local network settings first. Disable TUN, clear the system proxy, confirm that system DNS and the default route have returned, and test an ordinary connection without the client. Only after the basic network works should you restart the client and inspect the node. Switching nodes repeatedly at the outset can leave an incorrect system proxy or virtual route in place, making every node appear broken.

When a mobile connection drops, first check whether the network changed from Wi-Fi to mobile data, whether the client is restricted in the background, and whether the system’s traffic-capture indicator is still present. If a desktop client does not recover after sleep, stop the connection and restart the core so old sockets and DNS state are rebuilt. If the issue recurs frequently, inspect startup behavior, sleep policies, and logs showing network-interface changes.

Create a monthly maintenance checklist

Once the setup is stable, a light monthly check is enough: update the subscription and remove clearly invalid local copies; check for compatibility updates to the client and core; confirm that rule data loads correctly; clean up oversized log files; verify startup behavior and restoration of the system proxy on exit; and test routing with one direct destination and one proxied destination. Record the date, change, and rollback method for each edit. When a failure occurs, this lets you start with the latest change instead of resetting the entire environment.

When moving to another device, export any local settings the client supports and separately record the subscription entry and custom rules. On the new device, install the client for the corresponding platform, restore the subscription, and migrate routing and TUN last. Paths, process rules, and network-interface names differ between operating systems and should not be copied directly. For the fastest setup, return to the quick-start guide →; for client differences, see the selection guide →.

08
Understand the underlying configuration

Advanced path and configuration-file structure

Map graphical options to the underlying configuration

At the advanced stage, you do not need to abandon the graphical client immediately. A more effective approach is to export or inspect the runtime configuration it generates and map the interface’s local port, current node, routing mode, and DNS options to JSON fields. The system proxy is an operating-system setting and may not appear directly in the core configuration; local SOCKS or HTTP ports are in inbounds; nodes and direct exits are in outbounds; split routing is in routing; and domain resolution is in dns. Understanding this mapping lets you tell whether an interface switch changes the configuration file or the system environment.

Clients usually regenerate the runtime configuration each time they start, so edits to a temporary file may disappear at the next launch. For long-term custom JSON, use the client’s custom-configuration entry point or write the change into its supported template or routing editor. Copy the original configuration first and use a JSON parser to check syntax. JSON does not allow comments, trailing commas, or unescaped special characters; these are common direct causes of a configuration that looks correct but prevents the core from starting.

What a minimal configuration needs

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "server.example.com",
            "port": 443,
            "users": [
              {
                "id": "11111111-2222-3333-4444-555555555555",
                "encryption": "none"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "tls",
        "tlsSettings": {
          "serverName": "service.example.com"
        }
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom"
    },
    {
      "tag": "block",
      "protocol": "blackhole"
    }
  ],
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "ip": [
          "geoip:private"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

This example shows structural relationships and does not include a connectable service. The inbound listens only on 127.0.0.1, so it accepts local requests only; changing it to listen on all interfaces expands the accessible range and requires consideration of firewall rules and authentication. The proxy outbound uses example VLESS parameters; in real use, replace the address, port, id, transport, and TLS fields. The direct and block outbounds provide routing targets, with private addresses sent to direct first and unmatched traffic handled according to the core’s default behavior.

Inbound and outbound tags are configuration connection points

tag does not encrypt traffic or connect to the network; it is an internal reference name. Routing selects an outbound through outboundTag and can use inboundTag to limit a rule to a particular inbound. Tag spelling must match exactly, and every reference must be updated when a tag is renamed. As configurations grow, use purpose-based names such as socks-in, tun-in, proxy, direct, and block rather than numeric identifiers.

Multiple inbounds can use different routing strategies. For example, a local browser SOCKS inbound can use ordinary rules while a TUN inbound handles DNS additionally; multiple outbounds can represent different nodes or connection methods. You can organize this with balancers or more complex routing structures, but do not add them without a clear need. If the graphical client already manages node switching adequately, manually writing multiple outbounds makes subscription updates harder to synchronize.

Learn to validate configuration before adding features

Configuration validation has three layers. First, check JSON syntax so brackets, arrays, strings, and commas are correct. Second, validate the core configuration, confirming field names, protocol structures, and tag references. Third, validate runtime behavior by checking port listening, route matches, and successful handshakes. Valid syntax does not prove that protocol parameters are correct, and a started process does not prove that an application is using the inbound. After adding each outbound or rule, repeat all three checks.

Complex configurations are best built as small, testable stages. Keep one SOCKS inbound and one proxy outbound first, and confirm that a browser with a manually configured proxy can access the web. Then add direct and basic routing, followed by DNS, and add TUN last. If the client can show the final runtime configuration, use that file as the source of truth because interface templates may automatically add mux, logging, policy, or DNS fields. For a detailed walkthrough, read configuration-file structure explained →.

Protocol choice must follow server parameters and compatibility

VMess and VLESS are both widely used protocols in the ecosystem. VMess includes its own authentication and data-processing mechanisms, while VLESS has a leaner structure and is often combined with security layers such as TLS and REALITY. The client cannot choose the protocol independently: use a local configuration that matches the parameters provided by the server. Performance cannot be judged separately from network quality, transport, encryption layers, and device capability. Most users should prioritize core support, matching parameters, and connection stability before optimizing transport overhead.

When a subscription offers several protocols, test connection establishment, long-lived connection stability, and recovery after switching between mobile data and Wi-Fi in the same network environment. Do not compare protocols using only one port probe. For protocol concepts, read VMess vs. VLESS →. For OpenWrt main-router or side-router deployment, first understand the device’s inbound, transparent capture, DNS, and routing responsibilities, then see OpenWrt deployment essentials →.

Create your own progression path

Break further learning into four stages. First, explain the path between the application, system proxy, local inbound, and remote outbound. Second, write direct rules for private networks, proxy rules for selected domains, and blocking rules, then confirm matches from the logs. Third, handle TUN, DNS, MTU, and LAN bypass independently. Only in the fourth stage should you move to multiple inbounds, multiple outbounds, process-based routing, or transparent router capture. Keep a minimal working configuration as a rollback baseline at every stage.

“From zero to advanced” does not mean enabling every option. It means being able to identify where a request stops: whether the application sent it to the local port, whether DNS returned the expected result, which outbound the route selected, and whether the core completed the remote handshake. Once you can answer these four questions, the client interface, JSON configuration, and system network settings fit into one model. To choose an installer again, return to the client download page →; to rebuild the setup using the shortest path, return to the quick-start guide →.