INSTALL / SUBSCRIPTION / ROUTING
V2Ray Setup Guide for Windows, macOS, Linux & Android
Set up v2rayN on desktop and v2rayNG on Android. Follow the steps for your platform, then troubleshoot by tracing the traffic path.
This is a reference manual, not a guide you need to read from start to finish. For your first connection, follow the main steps in the Getting Started guide. Return to the relevant section when you run into installation, permissions, routing or DNS issues. The guide gets you connected; this manual explains which layer each setting affects.
General setup: installers, configuration and traffic coverage
Check your client and device architecture first
For desktop, v2rayN is the recommended choice. On Android, v2rayNG with the Xray core is the first choice; consider v2flyNG if you need the V2Fly core. The client edits configuration, manages subscriptions and starts the core; the core establishes the connection. They operate at different layers. Switching clients can change the interface and how traffic is routed, but it cannot automatically fix a server-side configuration error. Before installing, note your operating system, processor architecture and which apps need a proxy. That way, you can choose the right package without guessing.
Most Windows desktop packages use the x64 architecture. On macOS, distinguish Apple Silicon from Intel; on Linux, check both processor architecture and package format. Most Android devices use arm64; if you are unsure, consider the universal build. A 64-bit operating system does not necessarily mean the processor uses a particular architecture. Check the processor type in system information, then choose the matching option in the Download Center. Never rename an installer for one platform to make it look like a package for another.
You need valid connection details; example addresses won't connect
Installing a client is only the first step. You also need a valid subscription URL, share link or manual configuration. A subscription is usually a web URL that returns a list of nodes; a share link usually starts with a protocol name and describes a single configuration. This site covers client setup; obtain connection details from a service you are authorized to use. The server address, port, user ID, transport and security settings are all connection parameters. Missing even one can let an import succeed but prevent the handshake.
When saving a subscription, give the group a recognizable name that describes its purpose, such as “Work” or “Test”. The name is a local note and does not affect how the connection works. Don't expose a full subscription URL, user ID or QR code in shared screenshots; these details may grant direct access. Example domains and fields in this manual only illustrate the format. They are not connectable services. Pasting a teaching example into your client and waiting for it to connect just adds a pointless task to your day.
System proxy, TUN and routing each handle a different layer
A system proxy registers a local proxy address with the operating system. Apps that honor this setting send their requests to the client, but it does not force every program to comply—especially apps with their own network stack, some command-line tools and apps with a custom proxy setting. TUN receives traffic through a virtual network interface. It typically covers more traffic, but requires the appropriate permissions and is more likely to conflict with other virtual adapters. Routing takes effect after traffic reaches the core: it decides whether to send traffic through a proxy outbound, a direct outbound or a blocked outbound.
| Setting | Where it applies | What to check |
|---|---|---|
| System proxy | Traffic entering the local listener | Whether the app uses system proxy settings |
| TUN | Virtual interface and system routes | Permissions, adapters and traffic capture conflicts |
| Routing rules | From core inbound to outbound | Rule order and match conditions |
| DNS | DNS resolution | Resolution path, reachability and cache |
For your first setup, use the system proxy to verify browser access before enabling TUN. Don't run two clients that compete for the same local port, or let two traffic-capture tools modify the default route at the same time. Android VPN capture works differently from a desktop system proxy, but the troubleshooting approach is the same: first confirm that traffic reaches the client, then check which outbound it uses. Setting routing to global cannot make traffic appear in the logs if it never entered the core.
Establish a test baseline you can roll back to
For your first test, use a known-good node, keep the default transport settings and leave Mux off for now. Record the routing mode, local listening port and traffic-capture method; change only one setting at a time. Make sure the device clock is accurate, or certificate validity checks may fail. Confirm that the underlying network works before connecting. If the network requires browser-based sign-in, complete that first. Until the basic network connection is up, both subscription updates and nodes may time out. There's no point in investigating routing yet.
Back up client settings and subscription groups before installing or upgrading, and store them somewhere only you can access. Backups contain sensitive connection details, so don't put them in public documents. When troubleshooting, keep the error type, timestamp and steps to reproduce; that is more useful than a screenshot showing only red text. The platform sections below follow the same flow: choose a package, install, import, route traffic and restore settings on exit. If you already have a working setup, check only what differs; there's no need to start from scratch.
Windows: v2rayN installation and system proxy
Choosing between the Desktop and Classic WPF versions
The Download Center offers v2rayN Desktop and Classic WPF. Desktop uses a newer cross-platform interface; WPF retains the classic desktop experience. If you're installing for the first time, start with Desktop. If you're used to WPF, you can keep using its download option. Menus may appear in different places between versions, so this chapter refers to feature names rather than assuming a button is in a particular spot. Don't copy program files from one version over the other; that can mix settings and dependencies.
Get the package from the Windows download page, then install or extract it according to its format. If it needs extracting, unpack the entire archive into its own folder; don't run the main program from inside the compressed archive. Choose a simple path in a location your current user can write to. The app may need to write configuration, logs and core files. Protected folders, on-demand files in sync folders and temporary directories can prevent the app from finding resources at startup or saving settings on exit.
First launch and runtime checks
After launch, check that the main window appears normally, then look in the log for core startup errors. An open window only confirms that the interface started, not that the core is running. If Windows reports that a .NET runtime is missing, install the runtime specified by the package instructions. Don't guess and install a similarly named component. Self-contained packages and packages that rely on the system runtime have different requirements. Reading the error first is faster than repeatedly reinstalling.
If security software blocks the core, first confirm that the blocked file came from the client package you just installed, then check the system's protection history. Don't disable all protection and hope for the best. If the app closes immediately on launch, check that extraction completed, the folder is writable and no other instance is running; then review the application error log. For more help with startup issues, see Troubleshooting v2rayN crashes on launch. There's no need to change connection settings yet.
Import subscriptions and select an active node
Create a group in “Subscription Group Settings”, enter a group name and subscription URL, and save. Back in the main window, open the “Subscription Group” menu and choose “Update subscription without proxy”. When you don't yet have a working node, updating without a proxy is usually the easiest way to establish a baseline. If the subscription site requires an existing connection, choose “Update subscription via proxy” instead—but only if you already have a working node. An empty list can't download its own first configuration.
When the update finishes, check the node list and its group, then select a node and set it as the active server. Highlighting a row doesn't necessarily make that configuration active; check the status shown by the client. To import a share link, use “Import share links from clipboard”—don't paste it into the subscription URL field. If the field is empty after import, check whether the original link was truncated by a chat app. Pay particular attention to trailing parameters and percent encoding; don't delete parts just because they look complicated.
Start with the system proxy; enable TUN only if needed
Once the core is running, choose “Set system proxy automatically” under “System Proxy”. In a browser, visit an address that requires the current connection, then check the client log for the corresponding request. If it works in the browser but not in another app, first check whether that app uses the system proxy. Some apps have their own proxy fields; enter the client's local HTTP or SOCKS address there. Use the port shown in the client, not a default number copied from another guide.
Enable TUN only if you need to capture traffic from the whole device. It usually requires administrator privileges or initialization of a component; follow the client prompts. Exit other proxy tools first and check that no virtual adapter is still capturing traffic. If TUN fails while the system proxy works, the issue is more likely with permissions, adapters or system routes than with the server. Don't change DNS, routing rules and transport settings at the same time during testing, or you won't know which change fixed the connection.
Restore settings on exit and avoid common pitfalls
Closing the main window may only minimize the app to the system tray. To stop traffic capture, first choose “Clear system proxy” under “System Proxy”, turn off TUN, then exit from the tray. If the app crashes, the system proxy may still point to a local port that is no longer listening. Open Windows proxy settings and check for a leftover manual proxy address. Clear it and confirm direct access works before restarting the client. Also check browser proxy extensions; they may not follow system proxy changes.
For startup on login, prefer the client's built-in setting and confirm that it actually runs after the current user signs in. If the app starts but TUN doesn't, permissions may differ; don't try to fix it by creating multiple startup entries. Before upgrading, exit the old process and back up your settings. Afterward, recheck the system proxy, active server and local port. If the port is in use, identify the process or choose a free port, then update the app configuration too. Don't change only one side.
macOS: choose a build by chip, then configure network access
Install v2rayN for your Mac's processor
Open “About This Mac” and check whether it lists an Apple chip or an Intel processor. Choose the arm64 download for Apple Silicon or x64 for Intel. Processor architecture determines which package to use; language and screen size do not. Get the matching disk image from the macOS download page, open it and follow the prompt to move the app to “Applications”. Don't keep running it from the disk image or Downloads folder; that can cause issues with updates, login items and file permissions.
If macOS asks you to confirm the first launch, check the app's source and make sure it's the client you just downloaded, then follow the prompt in “Privacy & Security”. Don't disable system-wide security to launch one app or run an untrusted bypass script. If the error says the architecture is incompatible, go back to the download page and choose the right package. Whether translation support can run a particular build depends on how it was compiled; don't count on it to fix a package mismatch.
Import a subscription and verify the core is running
Go to “Subscription Group Settings”, add a name and URL, save, then update the subscription. If no node is active, try updating without a proxy first. If you have a working node and the subscription URL requires a proxy, update through the proxy instead. Once the list appears, select an active server and check whether the core log shows startup activity. The app window, subscription retrieval and node connection are three separate steps. Success at the first two doesn't guarantee the third.
To import a share link manually, use “Import share links from clipboard”. The clipboard should contain the complete link only, with no explanatory text or chat quotation marks. After importing, check the address, port, transport and TLS-related fields. A password manager or another app may clear the clipboard automatically; if the link isn't recognized, copy it again and retry. Don't keep creating identical subscription groups after one failed import. Duplicate groups make later updates harder to track.
System proxy and the active network service
Enable automatic configuration in v2rayN's “System Proxy” feature, then verify it in a browser. macOS proxy settings apply to a specific network service. After switching between Wi-Fi, Ethernet or another interface, the active service may change. If the connection stops working after a network change, check the proxy settings for the active service under “Network” in System Settings, then have the client apply them again. Check the service currently in use, not just any interface you've connected to before.
Apps may also have their own proxy settings. If one browser works but another app doesn't, first check whether the second app uses the system proxy. If needed, configure its local HTTP or SOCKS inbound explicitly. Use the address and port the client is actually listening on; the local address is usually the loopback address, not the remote server. Entering the remote node's port as the app's local proxy bypasses the client's protocol handling and usually leaves the app waiting for a connection.
TUN permissions and network changes
TUN captures traffic from apps that don't use the system proxy. Before enabling it, confirm that your build supports the feature and complete the required permission steps. If elevated privileges are requested, read what the operation will do; never put your system password in a configuration file or script. For the first test, keep the verified active node and default rules, and change only the traffic-capture method. If TUN fails but the system proxy works, continue using the system proxy while checking virtual interface initialization and permission logs.
Other VPNs, network filters and virtual machine networking components can all affect routing. For troubleshooting, temporarily exit one traffic-capture tool and see whether the problem goes away rather than restarting everything at once. Waking from sleep or switching networks can invalidate an old connection or interface state. Stop and restart the client connection first to rebuild the session. If that doesn't help, re-enable TUN; don't delete your entire configuration as soon as the Mac wakes up.
Exit, upgrade and restore network settings
Before quitting, clear the system proxy and turn off TUN. Confirm direct access works, then exit the app. If the network stops working after an unexpected exit, check whether the active network service still points to a local proxy that is no longer listening. Other apps will keep trying to connect to that local port as long as the proxy address remains; that doesn't mean the network suddenly broke. If clearing the leftover proxy doesn't restore access, check other traffic-capture tools and system DNS settings one layer at a time instead of doing a blanket reset.
Before upgrading, back up groups and settings, quit the running app, then replace the program. If the app fails to start at login, check for conflicts between Login Items and the client's startup setting; keep one clear startup method. Before removing the app, stop traffic capture. Dragging it to the Trash alone does not guarantee that all network settings are restored. Export your data before clearing the configuration folder, especially manually created nodes that cannot be recreated by updating a subscription.
Linux: package installation, desktop proxy and startup
Check package format and architecture separately
v2rayN is the recommended choice for Linux desktops. Ubuntu and Debian typically use deb packages; Fedora and openSUSE typically use rpm. Also check whether your device is x64 or arm64. The right package format with the wrong architecture still won't run. Choose the matching package from the Linux download page; changing a deb file's extension doesn't make it an rpm. Confirm the distribution, package format and processor architecture separately before installing. Don't guess the distribution from its desktop theme.
This chapter focuses on graphical installers: download and open the package, check the app name, dependency prompts and installation target, then follow the system prompts to authorize installation. If the installer reports missing dependencies, use your distribution's own package manager to install them. Don't copy shared libraries from another distribution into system folders. If an older version is installed, exit it before upgrading. Seeing the app in the menu confirms that the desktop entry exists; you still need to check that it launches.
First launch and folder permissions
Launch v2rayN from the app menu and check the main window and core log. Run the desktop app as a regular user; don't run the entire client as an administrator just to get around a permission error. Configuration, cache and logs belong to the current user. Running under a different account creates a separate data directory, which can make it look as if your nodes have disappeared or settings won't save. Check whether your user directory is writable before blaming the app.
If clicking the icon opens no window, check that the desktop launcher points to the right program, confirm installation completed without missing dependencies, and review system application errors. If a graphical component, shared library or display environment is missing, proxy settings aren't involved yet; there's no need to change the subscription. A headless server is not the Linux desktop environment covered here. Graphical clients need a suitable desktop session, so don't apply desktop installation steps unchanged to a terminal-only machine.
Import configuration and understand system proxy limits
Once the app starts, save the subscription URL under “Subscription Group Settings”, update without a proxy and select an active server. Treat subscription updates and connection tests separately: seeing nodes means the configuration was retrieved, not that a connection works. To import a single share link, use the clipboard import feature and keep the original link for reference. If multiple updates produce duplicate node names, distinguish them by group and server fields rather than display name alone.
After enabling “Set system proxy automatically”, test with a desktop browser first. Desktop environments don't all handle system proxy settings the same way. Some apps use desktop settings; others only recognize environment variables or their own proxy fields. If the browser works but a terminal program doesn't, the two may be using different proxy entry points. You don't need to enable TUN immediately, and global routing won't automatically cover every app. First check which proxy setting the program actually uses.
If an app needs a manual proxy, enter the client's local listening address and port in its settings, and choose the correct protocol, HTTP or SOCKS. If you change the client's port, update the app too; don't leave the old port in multiple configuration files. Check for system environment variables in the system or app environment settings. If they still point to a local proxy after the client exits, they will continue to affect programs and must be restored separately; “Clear system proxy” may not change custom environment settings.
TUN, permissions and distribution differences
TUN uses a virtual interface and system routes, so it usually needs extra permissions or a client-provided helper. Follow the prompts for your build rather than treating an unknown permission command as a required step. If enabling TUN returns a permission error, first confirm that authorization is complete, then check your distribution's security policy and logs. A security module may block a specific operation; identify what was denied instead of disabling the entire security policy.
Firewalls, other VPNs and virtual machine networking components can all affect TUN. Before testing, exit any other traffic-capture tool and make sure another process isn't using the local inbound port. If direct access works after a network change but TUN doesn't, restart traffic capture to refresh the routes. If the node works through the system proxy, focus on the virtual interface and routes instead of importing the same subscription again. Change one variable at a time and read the Linux error messages carefully; they often give you useful details.
Start on login and clean up before uninstalling
Desktop startup means the app runs after the current user signs in to a graphical session, not that it connects as soon as the machine powers on. Use either the client's startup option or the desktop environment's “Startup Applications” setting, not both. If the app starts but TUN doesn't, check permission initialization and the session environment rather than adding a second startup entry. Multiple instances may compete for a port and turn a stable setup into an intermittent one.
Before uninstalling or upgrading, turn off TUN, clear the system proxy and exit the process. Then use your distribution's package manager to handle the package. Configuration folders may remain separate from the program package; uninstalling the app doesn't necessarily delete connection details. Export your settings before migrating, and confirm the data scope before cleaning up. If network issues persist after uninstalling, check app-specific proxies, environment settings and other traffic-capture tools—not just the program files you've removed.
Android: import into v2rayNG and use VPN mode
Choose v2rayNG and install the right architecture
v2rayNG with the Xray core is the recommended choice for Android; v2flyNG, which uses the V2Fly core, is an alternative. Choose the alternative based on the core capabilities your configuration needs, not a similar-looking name or icon. Most Android devices use arm64; if you're unsure, consider the universal build. Get the right package from the Android download page and follow the system prompts to install it. Grant installation permission only to the download or file manager app you're using, then revoke it if you no longer need it.
If an update reports a signature mismatch, first confirm that the old and new packages are for the same client and come from the same publisher. Don't uninstall immediately; that may erase local nodes and settings, so back them up first. Installation can also fail because of an architecture mismatch, low storage or system compatibility requirements. The fix depends on the actual error. v2rayNG and v2flyNG keep separate app data; installing one won't automatically take over the other's subscriptions.
Import subscriptions and share links separately
In v2rayNG, add a group name and subscription URL under “Subscription Group Settings”, save, then return to the main screen and choose “Update subscription” from the menu. When the update finishes, review the configurations in the group and tap the node you want to use. Menu names and positions may vary between builds, but the roles stay the same: groups store URLs that can be updated, and the node list selects the configuration to connect with. If a new group has no nodes yet, you probably haven't updated it; that doesn't mean it failed to save.
Use “Import from clipboard” for a single share link. Copy the entire link; chat apps may copy only the truncated text shown on screen. QR codes are another way to import configuration, and the scan result must contain complete, readable data. If a QR code or link contains sensitive parameters, don't include it in a public help screenshot. After import, check the configuration fields, especially transport type, TLS and server name. Seeing a new entry in the app doesn't mean those fields match the server.
Authorize VPN mode and choose a routing mode
The first time you connect in VPN mode, Android displays a system authorization prompt. This lets the app create a local VPN interface to receive device traffic; it does not mean the remote connection is already working. After authorization, return to the client, check the connection button and logs, then test actual access. Android generally can't keep two VPN-based traffic-capture apps active at once. If the system says another app has replaced the connection, choose which one to use instead of letting them compete for control.
Check VPN mode and routing options under “Settings”. For everyday split tunneling, start with “Bypass LAN and mainland China IPs”; switch to global mode temporarily when you need a comparison. Routing controls the path of traffic that has already entered the client; it won't fix an incorrect server address. If an app is excluded from traffic capture, switching to global won't automatically send its requests through the core. When troubleshooting an app-specific issue, check app-level routing first, then the routing rules.
Don't copy the desktop guide's “Set system proxy” steps for Android VPN mode. Android typically sends traffic to the core through the system VPN interface, while desktop system proxy depends on apps honoring proxy settings. You can move connection details when using the same service, but traffic-capture controls must be set up separately on each platform. Some networks require browser-based sign-in; complete it before connecting the client, or the VPN and subscription update may both time out.
Background activity, battery settings and network changes
If the connection drops after a while, first check whether the system is stopping the app in the background. Battery management settings vary by device; look in the app info for battery optimization, background activity and auto-start restrictions. Change only the permissions this client needs; there's no need to grant them to every app. Notifications and foreground service status can help keep a connection active, but a notification doesn't guarantee the remote session is still working. After a network change, verify access with an actual request.
After switching from Wi-Fi to mobile data, the existing connection may need to be rebuilt. Stop and restart the connection first; compare DNS, server reachability and network sign-in only if a particular network still fails. Don't enable every advanced option just to fix one dropped connection. Leaving Mux off helps establish a baseline; enable sniffing only if your routing needs it. More advanced switches don't automatically mean more stability—they add more variables to troubleshoot.
Local DNS and checks before exit
For domain access issues, check settings such as “Local DNS” and consider the current routing and core behavior when tracing the resolution path. Options vary across cores and client builds; don't copy every value from an old screenshot. The resolver must be reachable through the selected network or proxy path. If IP addresses work but domain names fail, DNS is worth investigating. However, some services require the correct hostname and TLS settings, so using an IP address is not a complete fix.
Before exiting, stop the connection and confirm that Android has released the VPN. To switch to v2flyNG, stop v2rayNG, import a compatible configuration and authorize the new app; don't assume settings are shared. Back up subscriptions and manual nodes before uninstalling, then recheck routing and app-level traffic rules after migration. For common installation and connection questions, see the FAQ. When asking for help, share your system version, client name and a redacted error; don't post the full subscription URL.
Subscriptions and migration: URLs, node lists and local changes
A subscription URL is not a node address
A subscription provides a configuration list; a node in that list is an individual connection entry. The former may be a regular web URL, while the latter includes a protocol, server, port and authentication parameters. Updating a subscription downloads and parses the list; it does not test every server. Verify “update succeeded” and “node works” separately. A share link usually describes one node and is useful for a one-off import, but it doesn't stay synced with the subscription. If the service changes, you'll generally need a new link.
Query parameters in a subscription URL may authorize access; don't keep only the domain and path. If the trailing parameters are missing, the server may return an error page, sign-in page or empty response. Opening the URL in a browser doesn't guarantee the client can parse it: a web page and subscription data are different kinds of output. Use the client subscription URL provided by the service, not the account page URL. For help identifying a complete link, see Share links vs. subscription URLs.
Updating with or without a proxy
Updating without a proxy usually fetches the subscription over your current network connection. Updating through a proxy uses an existing local proxy connection. If you don't have a node yet, try without a proxy first. If that fails and you have a working connection, try through the proxy. Both methods fetch the same list; choose based on whether the subscription site is reachable, not on which one is supposedly faster. If the existing connection is unstable, updating through it can turn one problem into two.
When an update fails, identify the stage: DNS resolution, connection, TLS handshake, server response or content parsing. A parsing error often means the response isn't in subscription format; a connection error calls for checking the URL and network path. An inaccurate system clock can also cause secure connections to fail. Creating the same group again won't change any of these conditions; it only adds duplicate entries. Keep the original group, record the full error once, then check network access and response content separately.
Group names and changes after an update
Create groups by source or purpose, using a name that's easy to recognize. After an update, the number, names and order of nodes may change, and you may need to recheck which one is active. A display name is just a label, not a reliable identifier: nodes with the same name may have different addresses and ports, while differently named entries may point to the same service. Check the protocol and server fields when choosing a node; don't rely on list order. Automatic test results are only a guide for your current environment—always verify with the app you actually use.
Local edits to subscribed nodes may be overwritten at the next update. For a custom setup you need to keep, copy it to a separate manual configuration area and note why you changed it. Don't edit a subscribed node directly and lose track of its source. If the server address or authentication details change, the copied configuration won't update automatically; you'll need to maintain it yourself. Subscriptions reduce manual updates, while manual configurations preserve one-off changes. Each has its limits—you can't expect a configuration to be both fully automatic and immune to updates.
What to keep when moving between platforms
When moving from desktop to Android, add the subscription URL again so the new client can generate a configuration in its own format. You can also move a single node with a share link. Don't copy all app settings from one platform into another: local ports, paths, system proxy and traffic-capture methods aren't interchangeable. Protocol parameters and service details are broadly portable; permissions, interfaces, background policies and app-level routing are platform-specific and need to be checked on the new device.
Importing a full configuration works best when you understand the target core's format. Xray and V2Fly share some configuration concepts, but differ in supported fields and features. A client supporting a protocol name doesn't necessarily support every related transport combination. If migration reports an unknown field or unsupported security mode, check what the target core supports before deleting anything. Removing a field may let the file start, but it can change how the connection works and move the error from startup to the handshake.
Backups and practical redaction
At minimum, back up subscription groups, manual nodes and important routing settings. Store them somewhere you control, label them with the source client and backup date, and keep files from different platforms separate. Before restoring, confirm that the target client supports the backup format. When troubleshooting, edit a copy for redaction; don't modify your only backup. You can re-add a lost subscription, but manual parameters without a backup may not be recoverable from the app's history.
Check the active node before and after scheduled subscription updates, especially after the service changes node names or list structure. Automatic updates don't repair connections, and an update timestamp doesn't prove a node is healthy. If a subscription keeps returning unreadable content, ask the provider which client format it supports before trying another import method. After troubleshooting, remove duplicate test groups and keep one configuration with a clear source and purpose. That makes future issues easier to trace.
Routing and DNS: trace the path from inbound to outbound
First check whether traffic reaches the core
Routing only handles requests that reach the core. Rules can't run if a desktop app ignores the system proxy, an Android app is excluded from traffic capture or TUN failed to start. Before troubleshooting, check the request logs and confirm that traffic from the target app appears. If there's no entry, revisit the system proxy or traffic-capture settings. If there is an entry but the outbound is wrong, check routing. This order helps distinguish an inbound problem from a split-routing problem.
Global mode typically sends received traffic through a proxy outbound, while bypass mode routes selected destinations through a direct outbound. The system proxy toggle and routing mode are different: one gets traffic in the door, the other decides which path it takes. Mode names in the client map to specific rules, so check the generated configuration once you understand the concept. For a closer look at how the layers differ, see System proxy and routing modes explained.
Rule order and outbound tags
Common routing rules are checked in order, and the first match determines what happens. Put precise rules for specific domains before broader rules, or later exceptions may never take effect. An outbound tag is a reference name in the configuration, not a protocol name. If a rule uses outboundTag, an outbound with the same name must exist. A typo can cause startup errors or unexpected behavior; checking only the domain list won't catch a missing outbound.
The following routing snippet can be added to an Xray or V2Fly client configuration that already has a direct outbound named direct. It sends loopback and private addresses through that outbound; other requests use the default outbound defined in the full configuration. This snippet contains no remote service details and is not a standalone connection configuration. Private address rules help preserve local network access, but check whether your network uses any other special address ranges before deploying.
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"127.0.0.0/8",
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"::1/128",
"fc00::/7",
"fe80::/10"
],
"outboundTag": "direct"
}
]
}
}
domainStrategy and domain matching
AsIs mainly matches using the domain information already available. IPIfNonMatch tries to resolve the domain if no domain rule matches, then checks IP rules. IPOnDemand resolves the domain when the matching process needs IP information. These options describe behavior during routing; they are not system DNS settings. Even when field names look similar, resolution strategies for outbound connections and routing operate at different stages. After changing one, check which rule matches instead of only checking whether the domain opens.
In domain rules, full: matches an exact domain, while domain: matches a domain and its subdomains. Plain strings work differently; don't treat all forms as equivalent. When using rule data files, confirm that the core can find the files and recognizes their categories. For a first setup, the client's built-in routing is usually preferable to hand-writing a complete ruleset. Establish a baseline, then add only the exceptions you need.
Where DNS resolves and how failures happen
DNS resolves domain names to IP addresses. Resolution requests may come from the app, operating system, core or traffic-capture mechanism, depending on the configuration. If an app resolves a domain to an IP before sending it through the proxy, the core may no longer have the original domain. IP rules may work while domain rules fail to match. Sniffing can recover domain information from some protocol traffic, but not all of it; it isn't a universal switch for restoring domain names.
The resolver must be reachable through the chosen path. Sending a resolver that can't be reached directly over the direct path can cause domains to time out even when the node works. Making DNS depend on a proxy connection that hasn't started can create a startup dependency too. First distinguish server address resolution from target website resolution, then check for circular dependencies. When testing DNS, record the network, traffic-capture method and cache state. Stale cache entries after a network change can hide the real result; restart the relevant app if needed and test again.
Sniffing, Mux and how to verify changes
Sniffing can help with domain-based routing; Mux multiplexes connections. They solve different problems. Enabling Mux won't fix authentication failures, and it doesn't guarantee every transport combination will be more stable. For your first setup, keep the defaults and leave multiplexing off until the connection is stable. If interruptions begin only after enabling a feature, turn it off and test again. Advanced features should address a real need; enabling every switch isn't a meaningful success criterion.
When editing JSON, watch commas, quotation marks and array structure; don't add comments to the configuration. Keep the original file and make changes to a copy, then roll back immediately if startup fails. The client may rewrite generated configuration when you switch nodes. Save long-term rules in the client's routing settings instead of repeatedly editing temporary output. For more on the configuration layers, see A guide to configuration file structure, which covers inbounds, outbounds and routing separately.
Common configuration issues: troubleshoot by failure stage
The app won't open: this isn't a node connection issue
An app that closes on launch, never opens a window or reports a missing runtime has a startup problem. Check the package architecture, installation, folder permissions and runtime environment first. The core may not have read the connection configuration yet, so changing the subscription won't help. On Windows, check the runtime and extraction folder; on macOS, check the architecture and security prompts; on Linux, check graphical dependencies and the user session; on Android, check installation requirements and app data.
If the interface opens but the core won't start, check for a port conflict, invalid configuration format or unsupported core features. Two clients may compete for the same port; a leftover process can also prevent a new instance from listening. Stop extra instances, confirm the listening address and port, then try again. If an error names an unsupported field, check the current core's capabilities and the import format. Don't delete every advanced field and call it fixed; that may completely change how the connection works.
The subscription has nodes, but connections keep timing out
A timeout means a step didn't finish in time; it doesn't automatically mean the authentication details are wrong. First confirm the underlying network works and the server domain resolves, then check whether the remote address and port are still valid. If just one node times out while others work, focus on that service or configuration. If every node fails on one network but works on another, compare the network environment and resolution path. Only the service provider can confirm whether a service is available; the client can't determine the exact cause from a timeout message alone.
For TLS errors, check the device clock, server name and certificate requirements. The connection address and TLS server name serve different purposes and may not match. Don't change the server name to an IP just because the connection address is one. WebSocket paths, Host values, gRPC service names and other transport parameters must match the server. Importing a share link is usually more reliable than filling in missing fields by hand. If you must configure them manually, check each one against the original details instead of guessing from defaults.
The browser works, but other apps don't
When apps behave differently, check how their traffic enters the client. An app may ignore the system proxy, use its own settings, be excluded from Android traffic capture or send traffic the current inbound doesn't support. Check the client log to see whether it received the app's request. If not, adjust the app's proxy or traffic-capture settings; if it did, check routing and outbound selection. TUN can capture more traffic, but adds permission and routing variables. Enable it only after verifying the system proxy; it's not the first fix to try for every app issue.
If a site's home page loads but some resources don't, the issue may involve different domains, cached connections or protocol behavior. Note which resource failed and check whether a different rule handled it. Browser secure DNS and proxy extensions can also change the path; test with one clear configuration at a time. Don't judge the current connection from an old page that hasn't been refreshed. Cached content doesn't prove a new request works; reload the page or use a fresh session.
The underlying network stops working after you quit the client
A leftover system proxy is the first thing to check. The operating system may still send requests to a local address even though the client has stopped listening, causing every app that follows the system proxy to fail. Clear the system proxy first, then check that TUN is off and no other VPN is capturing traffic. On Android, also check the system VPN lockdown option. Once direct access works again, restart the client. If the problem happens only on exit, fix the exit and restore steps instead of switching nodes.
| Symptom | First layer to check | First step |
|---|---|---|
| App won't open | Installation and runtime | Read the system error |
| Core won't start | Configuration and local listener | Check ports and field errors |
| Subscription update fails | Subscription access path | Distinguish connection and parsing errors |
| Only some apps fail | Traffic entry point | Check whether the request appears in the log |
| Can't connect after quitting | Traffic capture left enabled | Clear the system proxy and stop TUN |
What to keep in logs and what to change during testing
Keep the timestamp, steps taken, error type and relevant field names in your logs. A screenshot of only the last line may miss the real cause; include a few surrounding lines where useful. Redact server authorization parameters, user IDs and full subscription URLs. Temporarily increasing log detail can help with troubleshooting; restore the usual level afterward to avoid generating excessive data. Logs may also contain destination addresses, so consider privacy when backing them up or sharing them.
Build a small comparison table: does the same node behave the same through the system proxy and TUN? Does the same configuration behave the same on another network? Does another node work on the same network? Change one thing at a time and record the result. If you switch nodes, change DNS and enable sniffing all at once, even a successful test won't tell you which change mattered. Once you find a fix, undo unrelated test changes and keep the smallest working configuration. Stability comes from settings you can explain, not from trying every option in turn.
If you still can't resolve the issue, gather the client name, operating system and architecture, traffic-capture method, failure stage and redacted logs, then check the relevant section of the FAQ. To get a connection working from scratch, follow the minimal steps in the Getting Started guide. To upgrade or choose another package, go to the Download Center and select the right platform. Reinstalling should be a last resort for environment issues; it can't replace checking the configuration parameters or service status.