Setup guide · Platform reference

v2rayN setup guide
and Android subscription setup

Install the client for your operating system, then check subscriptions, traffic routing, and routing rules. For your first connection, start with the quick-start guide. Use this page to look up architecture, permissions, background operation, and configuration details.

Desktop client: v2rayN Android clients: v2rayNG / v2flyNG Subscription groups → connection checks

Before You Begin: Requirements and Configuration Basics

Understand the Client, Core, and Subscription

First, identify which layer you’re configuring. v2rayN is a desktop GUI client that saves server details, manages subscription groups, generates runtime configuration, and controls the core. The selected core handles the actual connection. On Android, v2rayNG is the usual choice and uses the Xray core; consider v2flyNG when you specifically need the V2Fly core. A subscription is an address or content provided by your service provider, not a client account. Installing the app does not give you a working server, and an arbitrary web address is not a subscription. Get a valid subscription before moving on to the platform-specific steps.

Check your provider’s instructions for the subscription format, protocols, and usage limits. Subscriptions may contain share links, encoded collections of links, or configuration for a specific client; whether they work depends on the client’s supported formats. Don’t judge compatibility by a file extension alone, and don’t paste a complete runtime configuration into “Optional address Url.” For a single server share link, use the import-from-clipboard option. For a subscription URL, create a subscription group. These import methods use different data sources and have different update workflows.

Check Your Architecture, Clock, and Network

Before opening the Download Center, check your system information for the processor architecture and operating system type. Choose desktop packages that match your processor and distribution; your computer’s brand isn’t enough to determine compatibility. Windows system type, macOS chip, Linux machine architecture, and Android processor capabilities each determine the appropriate installer. A matching package format doesn’t guarantee your OS version meets the requirements. If you run into runtime, system API, or installer limitations, follow the installation prompts. Reimporting a subscription won’t fix an app that hasn’t started properly.

Enable automatic time synchronization and make sure the time zone and clock are correct. TLS certificate checks rely on system time, and a significantly incorrect clock can cause handshake errors across all servers. Next, confirm that your network can resolve regular domain names; sign in through a network portal first if needed. An unauthenticated public Wi-Fi network, captive portal, or local DNS problem can all look like a subscription request timeout. At this stage, check only basic connectivity—don’t enable TUN or complex routing yet. Start with the fewest settings needed for a repeatable connection, then add features one at a time.

Save Your Settings and Plan the Test Sequence

Before making changes, note your current system proxy state, local listening port, and subscription group names. When migrating from another client, close the old instance first to prevent it from occupying a port or changing system proxy settings. Treat subscription URLs as sensitive: their tokens may grant access. Redact full URLs, user identifiers, and server credentials in public screenshots. Example URLs in this guide only illustrate where to enter an address; they cannot be used to update a subscription and should not replace a URL you’ve confirmed is valid.

Work in this order: start the app, update the subscription, test a server, route traffic, then verify the exit path. Check each layer before moving to the next. Don’t change the core, DNS, routing, and proxy mode all at once, or it’ll be difficult to identify what caused a failure. For your first connection, follow the quick-start walkthrough, then return here for platform-specific details. If installation isn’t complete, fix that first. If the client test succeeds but your browser doesn’t, check whether the browser uses the proxy before replacing all your servers.

Windows: Installation and System Proxy

Choose the Desktop or Classic WPF Edition

Open the Windows download page and choose between the v2rayN desktop edition and classic WPF edition. The desktop edition uses a cross-platform interface; the classic WPF edition retains the traditional Windows desktop interface. Menus may differ, so don’t rely on fixed coordinates from screenshots of the other edition. Choose an installer that matches your system type from the available options and read its environment requirements. This guide refers to settings by name; it doesn’t assume every release uses the same installation method or guarantee compatibility with a particular OS version.

After installation, launch the app as a regular user and check that the main window, server list, and log panel open correctly. If your release needs to be extracted, unpack the entire archive into a writable folder; don’t run the app from the archive preview. Don’t move only the main executable and leave its supporting files behind. The installation folder and configuration folder may differ, so confirm where your data is stored using the client’s backup or configuration tools before migrating. If file writes fail, check folder permissions and security software logs before blaming the subscription.

Import a Subscription and Test a Server

Open “Subscription group settings,” add a group, enter a recognizable name, and paste the full URL into “Optional address Url.” Enable the group and save, then select “Update all subscriptions (without proxy)” from the “Subscription group” menu. When the update finishes, select the group and check for servers. If the list is empty, clear the search and filters first, then review the update result in the logs. A successful group update doesn’t mean a server can connect; the absence of a menu error isn’t proof that a connection was established.

Run a “Real connection latency” test for one server, then set a server that passes as active. TCPing is closer to checking whether the remote port is reachable; it doesn’t verify the protocol handshake, authentication, or the full request to your destination. Real connection latency also depends on the test target, so you’ll still need to test a browser request. Don’t test a large batch and draw conclusions from one result. Start with one server and one test target, check the logs for an outbound connection, then compare with other servers.

Set the System Proxy and Restore It on Exit

Once the core is running, select “Set system proxy automatically” from v2rayN’s system proxy menu. Then check the proxy status in Windows Settings and confirm the address points to your local machine and the port matches the client’s listening port. The system proxy only affects apps that follow this setting; some command-line tools, games, and standalone network apps won’t use it automatically. If your browser has a proxy extension or custom settings, use a single proxy source while testing so the extension’s direct-connection rules don’t override the system setting. A browser that opens a regular webpage isn’t necessarily using the active server.

Verify the exit path before deciding whether to use TUN. If you need TUN, grant the permissions requested by the client. Don’t run as administrator long-term just to troubleshoot a regular system proxy connection. If startup reports a port conflict, close old instances and check which other process is listening. If you change the port, update any apps configured manually as well. Clear the system proxy before closing the client, or apps may keep sending requests to a local port that’s no longer active. If the network stops working after sleep, a network switch, or an update, check the system proxy and core status before deleting all subscriptions.

macOS: Installation and Permissions

Choose the Installer for Your Chip

Check your chip or processor in About This Mac, then open the macOS download page. Choose the arm64 installer for Apple silicon or the x64 installer for Intel. Prefer the native package for your machine rather than treating compatibility mode as the default. Open the downloaded disk image and follow its instructions to move v2rayN to the Applications folder, then launch it from there. Don’t run it from the mounted disk image long-term; updates, file paths, and relaunching after closing the image can become confusing.

Read the system prompt the first time you open the app. If macOS blocks it because of its download source, confirm the file’s origin and use the relevant prompt in Privacy & Security. Don’t disable system-wide security to launch one app. If you see a clear warning that the file is damaged, the architecture doesn’t match, or a component can’t load, recheck the download, system requirements, and installation steps rather than forcing a bypass with an arbitrary Terminal command. Once the client window opens, check that the core can start too; a working interface doesn’t confirm the core is running.

Create a Group and Check the Network

In “Subscription group settings,” enter a name and an “Optional address Url,” save, then update the subscription. For the first update, try without a proxy. If the URL is only reachable through an existing connection, verify that connection first, then choose to update through a proxy. Don’t save a login page as a subscription file. After updating, select an active server and run a real connection latency test. Check the logs for repeated authentication or handshake errors. Interface language and menu placement can change between versions, but the relationship between the URL, group, and update method remains the same.

If you need a system proxy, let the client configure it automatically, then check the active network service in System Settings. Wi-Fi, Ethernet, and other network services may have separate proxy settings. After switching networks, make sure the service in use still points to the correct local listening port. If automatic configuration fails, follow the authorization prompt or configure it manually only if you understand the port type. Don’t interchange HTTP and SOCKS ports based on their names; check the client’s listening type and enter it under the matching system setting.

Understand App Proxy Settings, Permissions, and Network Recovery

If an app ignores the system proxy, check whether it has its own network settings. Command-line programs may read environment variables instead of the graphical system settings, so a difference between Terminal and browser requests doesn’t necessarily mean the server is down. Don’t test the same connection with a browser extension using one port and the system proxy using another. Use a single proxy source in the test app, then compare direct and proxied requests. When checking your exit IP, use the same destination and request method to avoid misleading results from cached pages or different address families.

Before enabling TUN, quit other traffic-routing apps and follow the current client’s instructions for permissions and required components. A toggle in the desktop interface doesn’t guarantee all prerequisites are met. If the connection fails after waking from sleep, stop and restart it, then check whether the default route and DNS have recovered. Test the active server again after switching networks. Before uninstalling or moving the app, turn off TUN, clear the system proxy, and quit normally. If the app is already gone but the network is still affected, remove leftover proxy settings in System Settings and check other network services before resetting the entire network configuration.

Linux: Installation and Desktop Environment Differences

Match the Architecture and Package Format

Check which package system your distribution uses, then choose v2rayN from the Linux download page. DEB and RPM packages are for different package management systems; x64 and arm64 are processor architectures. Both must match. A file being available for download doesn’t mean it can be installed, and renaming one format doesn’t convert it to another. Open the downloaded file with your distribution’s graphical software installer and review its dependency and permission prompts. If dependencies are missing, install them from your distribution’s repositories instead of assembling runtime components from unknown sources.

Run the read-only commands below in a terminal to check your machine architecture and system identifier. x86_64 usually corresponds to x64, and aarch64 usually corresponds to arm64, but check the package notes and distribution support. After installation, launch the app from the applications menu and watch for errors involving the display environment, runtime libraries, or execution permissions. A remote terminal, a headless server, and a regular desktop session are different environments. This guide covers the desktop GUI client, not deploying a graphical app as a headless service.

uname -m
cat /etc/os-release

Import a Subscription and Check the Desktop Proxy

Open “Subscription group settings,” create a group, save the subscription URL, and update it. Select an active server, then run a real connection latency test to confirm the core can make a real request before configuring the desktop proxy. If an update fails, determine whether the app can’t access the network, the URL is unreachable, or the response format isn’t recognized. The software installer being able to access the internet doesn’t prove the client uses the same proxy path; they may use different environment variables and network settings. Don’t keep switching package formats without evidence of an installation issue.

Linux doesn’t have one universal system-wide proxy switch. Desktop environments and apps vary in how they use proxy settings. After the client configures the system proxy, verify it in your desktop environment’s network settings. For apps that ignore desktop proxy settings, use their own configuration or a temporary proxy environment, after checking the client’s listening port and protocol. The example below uses a local port to demonstrate an explicit HTTP proxy request. Before running it, replace the port with the one shown in the client. This test isolates app settings and doesn’t permanently change the system proxy.

curl --proxy http://127.0.0.1:10809 --head https://example.com/

Handle Permissions, Containers, and Clean Exit

Use a regular user session for ordinary desktop connections. TUN needs access to a virtual network device and may change routes; the authorization process depends on the client and system, so follow the interface instructions. Don’t run the entire GUI app with elevated privileges long-term just for convenience. If the core logs indicate a missing device, insufficient permissions, or a failed route addition, fix that system issue before testing the server. If a port is occupied, find the process using it or change the listening port and update the app settings instead of repeatedly restarting the core.

In containers, sandboxed apps, and remote sessions, 127.0.0.1 may not point to the network environment where the desktop client is running. If an explicit proxy request fails, first check whether the app and client share a network namespace. Don’t immediately change the listening address to all interfaces. If you need LAN access, consider the firewall, authentication, and who can reach it. After logging out, sleeping, or switching desktops, check for leftover proxy settings. Clear the desktop proxy and stop TUN before quitting normally. Back up your configuration before updating the app, then check permissions again after installation instead of assuming the previous authorization still applies.

Android: Installation and Background Connections

Choose v2rayNG or v2flyNG

Open the Android download page. v2rayNG, which uses the Xray core, is usually the first choice. Choose v2flyNG only when you specifically need the V2Fly core and have confirmed protocol compatibility. These are different apps, not just different skins; their import results and supported protocols aren’t identical. For most arm64 devices, choose the matching installer. If you’re unsure of the architecture, consider the universal version and check the system requirements. A larger universal package doesn’t mean it includes more proxy features; packaging architecture and protocol support are separate things.

During installation, follow the system prompt to allow installs from the current source. You can revoke that permission afterward. Before updating, keep your subscription URL and any necessary configuration. If installation is blocked by a signature mismatch, read the prompt before taking action; uninstalling immediately could erase local data. After installing, open the client, import your data, and then connect. Seeing a server list doesn’t mean the app has permission to route network traffic. On the first connection, respond to the system VPN permission prompt. If you denied it, tap connect again and approve the request.

Import a Group and Establish a VPN Connection

In v2rayNG, open the subscription group section, add a name and subscription URL, save, and update the subscription. In some versions, the update option is in a menu; look for “Subscription group” and “Update subscription.” For a single share link, use the import-from-clipboard option instead of the subscription URL field. v2flyNG may use different menu names and layouts; follow its own subscription management options rather than assuming the controls match v2rayNG screenshots.

Select a server, tap connect, and approve the system VPN permission. A VPN status icon only means the system has established a traffic-routing tunnel for the app; it doesn’t confirm remote authentication succeeded. After connecting, run the client’s real connection test or visit a consistent test destination in your browser, and check the logs. Android VPN routing differs from a desktop system proxy, so you usually don’t need to configure a manual Wi-Fi proxy too. If an old Wi-Fi proxy is still set, check whether it points to a local port that no longer exists before troubleshooting further.

Manage Per-App Routing, Background Activity, and Network Changes

Before enabling per-app proxying, check whether the list means “proxy only selected apps” or “bypass selected apps.” These choices do the opposite, and choosing the wrong one can leave only the browser—or only a specific app—unable to connect. After changing the list, reconnect if the client requires it to apply the new selection. During troubleshooting, disable complex per-app rules and verify the full routing path first, then restore rules one at a time. Work profiles and secondary user spaces may have separate restrictions; a connected status in the main profile doesn’t mean apps in another profile use the same tunnel.

If the connection stops after the screen locks, check the app’s battery policy, background activity limits, and system cleanup settings. Allow the background activity the app needs using the options available on your device. Don’t disable every battery-saving feature; first check whether disconnections coincide with the screen locking or a cleanup event. Switching between Wi-Fi and mobile data may require reconnecting. Reconnect, then check server address resolution and the handshake result. Other apps that use the system VPN tunnel may conflict, so keep a single traffic-routing source active. When switching clients, stop the old connection before creating a group and connecting in the new app to avoid both apps competing for the tunnel.

Subscription Groups and Update Settings

Save Sources Separately and Choose the Right Update Method

Put subscriptions from different sources in separate groups. Use the group name to identify the source; it doesn’t have to match a remote server name. Paste the full subscription URL into “Optional address Url,” preserving query parameters and capitalization. Don’t add notes at the end. Chat apps may insert line breaks, spaces, or ellipses when copying, so check the start and end of the URL rather than rewriting the token by hand. Subscription URLs may contain access credentials; redact sensitive parts in backups, screenshots, and support requests. A local group name doesn’t change your remote account permissions or subscription expiry.

Use “Update all subscriptions (without proxy)” when your current network can reach the subscription URL directly. “Update all subscriptions (through proxy)” requires an existing working proxy path. If all your servers are down, the latter may be unable to connect, creating a dependency loop. Choose based on whether the subscription URL is actually reachable; neither method is always correct. If an update fails, keep the existing list, check the error, and then decide whether to switch paths. Don’t start by deleting every server—you could lose the connection you need to recover.

Understand Auto-Updates, Filters, and Request Headers

“Auto-update interval (minutes)” sets how often the client checks for updates. Actual checks also depend on whether the client is running, its timer, and network conditions; it doesn’t mean the provider guarantees a scheduled push. Update manually first, then choose an interval that follows your provider’s limits. Don’t poll repeatedly at very short intervals. Missing an update while asleep or offline isn’t necessarily a fault; try a manual update after reconnecting. Disabling a group may affect whether it’s included in updates. The client’s behavior determines whether its existing servers remain, so back up before changing this setting.

“Filter (regex)” selects servers by name. A filter doesn’t change whether a server is valid or fill in missing protocol parameters; an overly restrictive expression can leave the list empty even when the update succeeds. For troubleshooting, clear the filter and check whether the raw subscription contains recognizable data, then add simple conditions one at a time. Change “User-Agent” only when your provider requires it or you need to support a particular response format. Imitating another client at random may produce content the app can’t parse. Note where custom values came from, and restore the default request behavior when testing.

SettingWhat it doesTroubleshooting
Optional address UrlSpecifies the subscription sourceCheck the full URL and access permissions
Auto-update interval (minutes)Schedules periodic updatesVerify a manual update first
Filter (regex)Filters server namesClear it temporarily and try again
User-AgentAffects the request header and possibly the response formatFollow your provider’s instructions

Distinguish Subscription Data from Runtime Configuration

Updating a subscription may rebuild its server entries, so manual changes to subscription-generated servers may be overwritten on the next update. If you need to keep exceptions, first check whether the client supports a separate way to save custom settings. Don’t pile extensive edits onto data that may be replaced. Before deleting a group, read the confirmation prompt and check whether its associated servers will also be deleted. When migrating, back up data in a format supported by the client, then save your subscription URLs. Copying a temporary runtime configuration may not restore subscription links, filters, or app preferences.

The standalone Xray JSON example below creates only a local SOCKS inbound and a direct outbound. It illustrates the structure of runtime configuration; it doesn’t provide a remote proxy connection and isn’t subscription content. Don’t replace the client-generated configuration with it to “fix a server.” The protocol, transport, security layer, and server parameters must all match. For more on the configuration layers, read Xray vs. V2Fly core differences to check compatibility between your client and protocol.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct"
    }
  ]
}

System Proxy, TUN, and Routing

Choose How Traffic Enters, Then Set Outbound Rules

Think of system proxy, TUN, and routing as separate layers. The system proxy tells apps that follow the setting to send requests to a local port. TUN uses a virtual network device to capture eligible traffic. Routing rules then decide which outbound handles requests that have reached the core. These aren’t the same thing. “Global” usually means the default outbound policy for traffic that has entered the core; it doesn’t mean every app’s traffic is being captured. So under a system proxy, selecting Global won’t stop some standalone network apps from connecting directly. That doesn’t contradict the routing rules.

If you only need a browser and desktop apps that follow the system proxy, start there—it’s easier to observe and undo. Consider TUN only when you need to handle apps that ignore the system proxy. Before enabling it, note the original proxy state, quit other traffic-routing apps, and confirm the necessary permissions, virtual device, and components are available. Don’t enable TUN in multiple clients and then try to fix the conflict by changing routing rules. If the whole machine loses internet access after enabling TUN, turn it off to restore connectivity and check the logs. Don’t keep changing DNS while basic connectivity is unavailable.

Check DNS, Domain Strategies, and Rule Order

Routing matches the destination information the client actually receives. HTTP, SOCKS, TUN, and different apps may provide a domain name or only an IP address; don’t assume every request can match a domain rule. The AsIs domain strategy doesn’t resolve a domain specifically for routing. IPIfNonMatch tries to resolve the domain if no domain rule matches, so IP rules can be checked. IPOnDemand resolves it when a rule requires an IP address. Changing the strategy affects when resolution occurs; it won’t fix an unavailable DNS server.

Rule order usually matters: the first matching rule determines how a request is handled. Placing a direct rule for private addresses appropriately can keep LAN traffic from going through a remote server, but confirm the access scope you need. Entries such as geosite:cn and geoip:private depend on the relevant rule data and core support. Outbound tags must also match tags already defined in the configuration. Copying a “proxy” string without a corresponding outbound won’t create a connection. After changing rules, check the generated configuration or logs to confirm they loaded, rather than assuming they were applied because they appear in the interface.

FeatureWhat it doesWhat it doesn’t prove
System proxySends traffic from apps that follow the setting to a local proxyAll apps are routed through the proxy
TUNRoutes traffic through a virtual network deviceThe remote server authenticated successfully
Routing rulesSelects an outbound for traffic that has been capturedRules also apply to traffic that wasn’t captured
Real connection latencyTests a real request along a specific pathEvery site and protocol works correctly

Verify Traffic Routing and Keep a Way to Roll Back

For a reliable test, keep the active server and test destination fixed. Run a real connection latency test in the client, then send a browser request to the same type of destination and check the exit IP. For command-line apps, use an explicitly configured proxy as a comparison: if that works but the default request fails, first check how the app gets its proxy settings. If both fail, check the core, server, and routing. IPv4 and IPv6 may use different paths. If the exit results differ, check the address family before concluding that all traffic is bypassing the proxy. See system proxy setup and real connection latency testing for details.

To roll back, undo changes in reverse order: stop TUN, clear the system proxy, then quit the client normally. If you set proxy environment variables or app-specific proxies manually, restore those separately; closing the client won’t change settings saved by each app. LAN devices, remote desktops, and work networks may be more sensitive to routing changes, so keep a local access path available. Don’t expose the listening address on every network interface just to connect one app. If you need to share a proxy, assess access controls and firewall rules separately instead of reusing a local client setup as a LAN service.

Common Configuration Issues and Log Troubleshooting

Troubleshoot Startup, Subscription, and Connection in Order

Start with the earliest layer that failed. If the interface won’t open, check the installation, architecture, and runtime environment. If the interface works but the core won’t start, check the logs for port conflicts, configuration parsing errors, and permissions. If the core starts but the subscription update fails, check the URL, request path, and response content. Only investigate protocol settings and server reachability after the subscription succeeds but the connection fails. Don’t use reinstalling as a substitute for diagnosis; it may preserve the old configuration or erase useful evidence. Save the original error and note what you were doing before making the smallest possible change.

Read log errors in context. address already in use usually means a local listening port is occupied; it doesn’t mean the remote server refused the connection. For a JSON parsing error, check the relevant field, commas, and data types. For an unknown protocol or unsupported field, confirm the current core supports that configuration. Client-generated files may be overwritten at restart, so first fix the setting in the interface that generates them. See troubleshooting core startup and configuration errors to distinguish configuration generation issues from runtime environment problems.

Distinguish Certificate, Authentication, and Timeout Errors

For TLS errors, check the system clock first, then compare the server address, SNI, and certificate domain. The connection address and certificate name can differ, but they must match the provider’s configuration; don’t change them to a familiar website domain at random. Don’t disable certificate verification as a routine fix—it can hide a name mismatch or trust chain problem. For configurations such as REALITY, import the public key, short ID, server name, and other parameters together as provided. Don’t assemble them piece by piece from another server. For background, see time synchronization and SNI error guide.

A timeout means a step didn’t finish within the allotted time. Check whether it happened during DNS resolution, connection setup, the handshake, or the request to the destination. A refused connection differs from a timeout: it may mean nothing is listening on the target port, while a timeout may point to the network path or a slow remote response. Compare with another known-good server, then test a different network. Don’t change every protocol parameter at once. If all servers fail at the same time, check for leftover local proxy settings, DNS issues, a public network sign-in page, and whether the core is still running before assuming the entire subscription is invalid.

Record Reproducible Details and Restore Settings Gradually

When reporting an issue, include your OS, processor architecture, client name, traffic-routing method, failed action, and a redacted section of the logs. Don’t share a full subscription URL, authentication identifier, or configuration containing sensitive parameters. Saying “subscription update failed” or “the browser won’t load” is more useful than “it doesn’t work.” Include the trigger if the issue only occurs after the screen locks, when switching networks, or in a specific app. After recovery, restore filters, per-app rules, DNS changes, and custom routes one at a time, testing each before moving on.

The Subscription Updated Successfully. Why Is the Server List Empty?

Clear the server search and group filters, then temporarily remove “Filter (regex).” Check the update logs to see whether the client actually recognized any servers, not just whether the HTTP request completed. A login page, error page, or unsupported format can return content without producing usable servers. Confirm the subscription format with your provider before trying again.

Real Connection Latency Is Normal. Why Won’t the Browser Load?

Check that the active server and test destination match, then verify the system proxy address, listening port, and any browser-specific proxy settings. The client’s test path may differ from the browser’s. Compare with an explicitly proxied request to confirm whether traffic reaches the core, then check the route and DNS for the destination.

Why Did My Manual Server Changes Disappear After Updating the Subscription?

Stop editing the same subscription entry until you confirm whether an update overwrites server settings. Save any exceptions separately using a method supported by the client, and ask your provider to correct the original subscription parameters. Don’t rely on reapplying manual edits after every update, especially when security and transport settings need to match.

For help by issue type, visit the FAQ. To rebuild a minimal working setup, return to the subscription import steps. After restoring service, keep a working configuration and test notes. Next time, compare what changed instead of repeating the entire setup from scratch.