Advanced Use · Practical Reference Guide

v2rayN Advanced Configuration Guide

Subscription groups, routing rules, DNS, and traffic interception. Browse by configuration layer and trace issues along the request path.

This guide is for users who have already connected successfully. Getting Started covers installation, importing a profile, and verifying your first connection; this guide explains how settings interact and where complex configurations have limits. Haven’t installed the client yet? Visit the client downloads page to find the right v2rayN version for your system. For Android, the examples focus on v2rayNG. With v2flyNG, check that the core supports your configuration.

Subscription Groups and Server Filtering

Subscription groups store the source and update method; server entries store the parameters for individual connections. They are separate layers: changing a group note won’t change a protocol, and switching servers won’t update a subscription. Organize your sources before filtering and selecting servers to avoid mistaking a changing list for a connection problem. Name groups by purpose or source, and never put passwords, access tokens, or personal account details in notes.

Create a Group, Then Check the Update

In v2rayN, add a group under subscription group settings, enter a note and subscription URL, save it, then update that group. Keep the URL intact, especially any parameters after the question mark. When copying from a chat, check for trailing spaces, line breaks, and punctuation. After updating, inspect the group’s server list and choose an entry as the current server. Creating a group only saves the source; it does not download or parse its contents.

A subscription update follows a separate request path. Some networks can reach the source directly; others need an already working proxy. Try each method separately rather than repeatedly changing connection parameters. If the list is empty, check the update log for the response status and parsing messages. A webpage, login page, or access error is not a usable server list, even if the request itself succeeded. Checking whether the source is still valid is more useful than reinstalling the client.

Filtering Changes What You See, Not What a Protocol Can Do

Server filters usually match note text, and the control may be in group settings or the list filter area. Start with one clear keyword and confirm the expected entries remain visible before adding conditions. Some fields accept plain text; others accept regular expressions. Follow the field’s guidance. Don’t confuse list search with subscription filtering: search often changes only the current view, while an update filter may determine which entries are retained.

For fields that support regular expressions, use patterns like these to understand matching boundaries. A pipe matches either term, a start anchor restricts matches to the beginning of a note, and a negative lookahead excludes a term. Notes are set by the source and don’t prove what a connection can do. A protocol name in a note doesn’t guarantee the entry actually uses that protocol. Check the entry’s protocol, transport, and security fields, then confirm the selected core supports them.

Work|Backup
^Work
^(?!.*Test).*$

Keep Manual Changes Separate from Subscription Updates

Entries supplied by a subscription may be recreated during updates. Changes to their address, port, or security settings may be overwritten on the next refresh or create duplicate entries. For experiments you need to keep, copy the entry into a separate manual group and note why you changed it. That way, you can keep receiving source updates while distinguishing provider-supplied data from local test settings.

On Android, create a clearly named subscription group, update it, and check the results. The group screens and filtering features in v2rayNG and v2flyNG may differ; if there’s no dedicated filter, use group selection or list search rather than forcing the desktop steps to fit. A successful import only shows that the format was recognized. Check startup logs and make a real request to verify that the current core accepts the protocol fields.

Keep a brief update log: source name, update method, whether it succeeded, and any filter changes. If the list suddenly shrinks after an update, temporarily clear the filter and refresh. If the entries return, the filter—not the core—is the problem. If parsing still fails, use Connection Checks and Rollback to investigate the subscription request and server connection separately. Don’t keep importing the same URL and accumulating duplicate groups.

Routing Rules in Practice

Routing evaluates requests that have reached the core and chooses an outbound. The system proxy setting determines whether an app sends requests to the local proxy in the first place. If an app bypasses that entry point entirely, changing routing rules won’t help. Before writing rules, confirm the app’s traffic reaches the client, then check the actual proxy, direct, and block tags in the generated config. Don’t infer tag names from the UI.

Order Rules by First Match

For standard field-based rules, the first matching rule determines the outbound. Put specific exceptions first, followed by broader region or category rules. For example, if a test domain should use the proxy, put its proxy rule before a later direct rule that would otherwise match it. Separate rules don’t vote or stack; when one rule includes multiple different fields, those fields generally all have to match.

This routing object can be added to an Xray config. It proxies the specified domain and its subdomains, sends private and China IP addresses direct, then matches direct requests against the domain lists in use. The example assumes outbounds tagged proxy and direct already exist and that the core can read the required rule data. Client-generated tags may differ, so verify them before use.

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

Distinguish Domain Matching, IP Matching, and DNS Resolution

full:example.com matches only the exact domain; domain:example.com also matches its subdomains. A domain without a prefix may match by substring, potentially covering more than intended. Use a prefix when you need a clear boundary. Regular expressions are useful for domains with consistent naming patterns, not as a replacement for every ordinary rule. The more complex a rule is, the harder it is to tell which condition actually matched.

IP rules match the destination address; they don’t infer what a domain is used for. IPIfNonMatch attempts DNS resolution when no domain rule matches, then checks the resulting address. This makes routing dependent on DNS. If an app supplies only an IP address, the core may not know the original domain. Sniffing can recover domain information from some protocols, but it doesn’t work for all traffic and isn’t a reliable way to reconstruct every domain.

Rule TypeWhat It MatchesWhen to Use It
full:Exact domainFor exceptions targeting a single host
domain:Domain and subdomainsFor a family of related domains
geosite:Domain data setsDepends on the data set name and contents
geoip:IP data setsDepends on the destination address and data file

Verify Rules Beyond Checking Whether a Page Loads

After adding rules, restart or reload the core and check the logs for unknown tags, invalid fields, or missing rule files. Then make a fresh request to one specific target and check the outbound in the access log. Browsers may reuse existing connections, which can keep following the old route after a rule change. Close the relevant tabs or reconnect to avoid mistaking connection reuse for a failed rule.

If no rule matches, standard configurations fall through to the default outbound, usually the first item in the outbound list. The default route is part of the routing design too. When troubleshooting with a block rule, restrict it to one clearly defined test target and have a way to restore access. Blocking a broad category can also affect DNS, subscription updates, and connection setup, turning a simple matching issue into several problems.

Client routing presets and custom rules may both affect the generated configuration. After saving, check the effective rule order, not just the order in the editor. For syntax details, see How to Write Custom Routing Rules. To understand how the entry point and routing mode differ, see System Proxy vs. Routing Modes. During testing, move one rule at a time and keep a rollback-ready order.

DNS Configuration

Start by asking: which component is resolving the domain? The browser, operating system, client core, and remote egress can all be involved. Changing the client’s DNS may not affect encrypted DNS in the browser or the system cache. Tune DNS by tracing the request path: first determine whether the app submits a domain or an IP address, then identify which component queries the upstream server, and finally check where the DNS request exits.

Separate Target-Domain Resolution from Server-Address Resolution

Resolving the target website and resolving the server address serve different purposes, even though both use DNS. If the server is specified by hostname, it may need to be resolved before the proxy connection is established. Setting the only DNS path to use that not-yet-established proxy creates a dependency loop. First ensure the server hostname can be resolved over the underlying network; then configure DNS routing for target websites.

Client options such as “Remote DNS” and “Direct DNS” are usually abstractions used to generate a config, not necessarily one-to-one mappings to core fields. Check the field descriptions and inspect the generated config after making changes. Android VPN mode may provide apps with a dedicated DNS entry point; desktop system proxy settings may not capture all DNS requests. A working browser doesn’t prove the whole system uses the same DNS path.

Start with Clear Upstreams and Policies

This example shows a basic Xray built-in DNS object: send a defined domain set to one upstream and other requests to another. UseIP allows both address families to be returned, but the actual results depend on the upstream and network. The public resolver addresses shown are for illustrating the fields, not a universal recommendation. Check that they’re reachable on your current network before adding them. Configure the routing object separately to determine where these DNS queries exit.

{
  "dns": {
    "queryStrategy": "UseIP",
    "servers": [
      {
        "address": "223.5.5.5",
        "domains": ["geosite:cn"]
      },
      "1.1.1.1"
    ]
  }
}

Domain conditions are one way to select an upstream; they don’t necessarily prevent all fallback requests. If an upstream fails, some cores may try another server. Check which fields your core supports before restricting fallback behavior. Disabling all fallback just to enforce strict routing can turn a brief upstream outage into a failure to resolve every domain. Verify basic lookups first, then tighten the rules gradually.

Encrypted DNS Still Needs a Working Route

Encrypted DNS changes how queries are transported, but it doesn’t automatically fix an unreachable upstream or a connection loop. With an HTTPS upstream, you also need to account for the hostname’s initial resolution, connection address, certificate validation, and route. Before sending the encrypted upstream through a proxy, make sure the proxy itself doesn’t depend on that same DNS chain. If an app also uses its own encrypted DNS, the client’s domain-based rules may see only resolved IP addresses.

When troubleshooting address-family issues, check IPv4 and IPv6 connectivity separately. Returning only one address family can help narrow down a problem temporarily, but it isn’t a universal performance improvement. If the system has IPv6 addresses but no working IPv6 route, an app may try an unreachable path first. If a service is IPv6-only, forcing IPv4 will make it fail. Keep the original policy, change one query setting at a time, and compare the results.

SymptomCheck FirstHow to Verify
Domain won’t resolveUpstream reachability and routing loopsCheck the core’s DNS logs
Resolves, but connection failsAddress family, route, destination portConfirm the actual destination address
Only the browser worksApp-specific DNS vs. system DNSCompare app settings with system results

Changes may take time to show because of caching. Reconnect the app before testing, and clear the DNS cache using the method provided by your OS if needed. Don’t treat cache clearing as a permanent fix. System DNS lookups from the command line usually test the OS resolver, not the core’s DNS. Check the core logs to confirm whether the new settings handled the request. Record the test domain, returned addresses, and outbound rather than judging by page load speed alone.

A well-designed config makes it clear where each type of query goes instead of stacking multiple resolvers. If you add TUN or FakeDNS, the DNS entry point and returned results change; see those sections too. If resolution fails, switch back to one reachable upstream and confirm the basic connection works before reintroducing routing, encryption, and caching one at a time. This helps distinguish upstream, routing, and traffic interception issues.

TUN Mode

TUN uses a virtual network interface to receive IP traffic routed in by the operating system. It’s useful for apps that don’t follow the system proxy. It broadens traffic interception, but it doesn’t change the system proxy setting or force every request through a proxy outbound. After traffic enters the interception layer, routing rules still determine whether it goes direct, through a proxy, or is blocked. Before enabling TUN, verify the current server through the regular proxy entry point so you’re not troubleshooting both the entry point and remote connection at once.

Understand the Roles of Permissions, Routing, and the Core

v2rayN’s TUN implementation depends on its integrated traffic interception component and its configuration. A standard Xray snippet isn’t a universal TUN config. Creating the virtual interface, adding system routes, and intercepting DNS are separate actions, some of which require elevated permissions. Grant the required permissions as prompted, then check the logs for interface initialization. An enabled toggle alone doesn’t prove the routes are working.

Before enabling TUN, note the current default route, DNS settings, and any other network interception tools in use. Multiple components modifying the default route can cause routing loops or competing exits. For testing, use one interception method and temporarily disable other traffic-capturing tools. If you need access to LAN devices, shared folders, or a corporate network, record the relevant subnets first so you don’t lose access to the settings you need to change.

PlatformWhat to CheckOperational Note
WindowsVirtual interface, elevated privileges, firewallCreate the interface as prompted by the client
macOSSystem permissions, routes, and DNSKeep network settings recoverable
LinuxInterface permissions, routes, and resolverWatch for network management services overriding settings
AndroidVPN permission, app selectionUsually uses the client’s VPN mode

Keep proxy connections out of the interception loop

The proxy connection itself must be able to bypass the interception loop. If traffic to the remote server is sent back through the virtual interface, the core can end up trying to establish its own outbound through itself. Depending on the implementation, the client may provide outbound binding, process exclusions, or route exceptions. If you add a manual exception for a server address, account for DNS changes: a hard-coded old address may stop working when the source changes.

Direct LAN routing and system route exclusions aren’t the same thing. A direct outbound makes the core connect to the destination; a system exclusion keeps the request entirely out of the core. Printer discovery, broadcasts, and some local services may need the latter. Sending private IPs direct may not cover every use case. Test one specific local address first, then test discovery and adjust the appropriate layer based on what happens.

Start with the Smallest Interception Scope

For the first test, use the default, easy-to-understand interception settings. Open a known reachable destination, then test an app that doesn’t follow the system proxy. Check whether the app’s traffic appears in the core logs. If there are no entries, investigate system routes and app exclusions before changing servers. If requests appear but fail, check the outbound and DNS next. If app selection offers include and exclude modes, confirm which mode is active and what it means.

UDP, address families, and MTU are common edge cases. If web browsing works but some real-time apps fail, check UDP forwarding and firewall behavior. If small requests work but larger transfers stall, investigate path MTU. Don’t copy a fixed MTU value at random. Confirm the symptoms using logs and network diagnostics, then make small changes and compare. ICMP-dependent features may not be handled like ordinary TCP traffic.

When finishing a test, turn off TUN first, then check whether regular network and LAN access have recovered. If problems persist after closing the client, check whether the virtual interface, default route, and DNS settings were restored. Restarting the client and shutting down interception normally may trigger cleanup more reliably than killing the process. Don’t delete system routes without recording them. If you plan to keep TUN enabled, retain regular proxy mode as a fallback and note which apps or subnets need to be excluded.

FakeDNS

FakeDNS assigns a synthetic, internal-use address to a domain. The core then uses the mapping to recover the domain. Its purpose is to preserve domain information for domain-based routing, not simply to speed up public DNS lookups. A synthetic address isn’t a real server address and can’t be used outside the mapping and interception path that created it. Enable FakeDNS to solve a specific problem where an app loses the domain after receiving an IP address, not as a default speed-up switch.

The Mapping Must Work Across Both DNS and Connections

A working flow has three steps: the app queries an intercepted DNS entry point, FakeDNS returns a synthetic address, and when the app connects to it, the core recovers the domain from the mapping. An address pool alone won’t help if the app’s queries don’t reach the right entry point. Returning synthetic addresses without intercepting the subsequent connections makes the app try to reach addresses that aren’t routable on the public internet. FakeDNS is often used with transparent interception, but test both parts separately.

This snippet shows the Xray FakeDNS settings. fakedns defines the address pool, and the DNS server list references it. 198.18.0.0/15 is a test address range, not the address of a real website. The example doesn’t include the interception entry point or complete sniffing settings, so it isn’t a runnable solution by itself. If v2rayN’s interception component implements its own synthetic address mechanism, use that component’s fields rather than mixing in another core’s configuration.

{
  "fakedns": [
    {
      "ipPool": "198.18.0.0/15",
      "poolSize": 65535
    }
  ],
  "dns": {
    "servers": ["fakedns"]
  }
}

Pool Size and Reuse Affect Mapping Lifetime

The address pool needs enough space and must not overlap with existing networks. Corporate networks and test environments may already use similar test ranges, so check the routing table first. Pool size controls how many mappings can be maintained; it isn’t a measure of network capacity or connection speed. Mappings may be recycled during long sessions while apps still cache old results. When the core restarts, mappings are rebuilt, and the same synthetic address may then refer to a different domain.

Sniffing settings can help the core obtain domain information, but distinguish reading the domain from rewriting the destination. Restoring a domain through a FakeDNS mapping is different from extracting a domain from HTTP or TLS. Check how the interception component implements destination recovery before assuming that routing-only sniffing is enough. Prefer options supplied by the client, then inspect the generated config to confirm they’re all active.

Keep Exceptions for Apps That Need Real Addresses

Some apps pass DNS results to another process, save them in a config file, or use returned addresses to establish LAN sessions. This can take synthetic addresses outside their original interception path. In those cases, configure real-resolution exceptions by domain or app. Test LAN device discovery, address-sensitive services, and tasks that share DNS results with other machines separately. Don’t switch every query to synthetic addresses at once.

If an app uses its own encrypted DNS, its queries may bypass FakeDNS and return real addresses. That doesn’t necessarily break the connection, but it changes the conditions for domain-based routing. Conversely, if system DNS returns a synthetic address but the app’s connection bypasses interception, the connection may fail outright. Test both the DNS query path and the connection path; the DNS response alone doesn’t prove the feature is working.

After disabling FakeDNS, make the app stop using old results and reconnect; clear both system and app DNS caches if needed. Otherwise, requests may still use stale synthetic addresses, making the network appear worse after the feature is turned off. To verify rollback, check that queries now return real addresses and that the same target works through the original DNS and routing path. Check cache recovery and core recovery separately.

Enable FakeDNS only where preserving domain information is genuinely necessary. If one app has problems, switch it to real DNS and compare results instead of expanding the address pool or repeatedly restarting. If regular DNS and proxy mode meet your needs, keep the simpler setup. For differences in core capabilities, see Xray vs. V2Fly Core Comparison. Don’t assume fields from one implementation are supported by every client.

Managing Multiple Subscriptions

Managing multiple subscriptions is about keeping sources separate, tracking updates, and knowing which server is active—not merging every address into one giant list. Different sources may reuse notes, use different protocols, or update on different schedules. Mixing them makes it easy to pick the wrong entry. Create a separate group for each source and use notes to identify its purpose. That keeps updates, deletions, and troubleshooting within a clear scope.

Separate Source Data from Local Usage Policies

Source data includes the subscription URL, returned entries, and server parameters. Local policies include group notes, list filters, the current selection, and routing rules. Avoid putting local policies into parameters that get refreshed by the subscription. A group labeled “Work” is only an organizational convention; it doesn’t automatically route work apps through that group. Binding apps to outbounds requires routing rules or a client feature that supports it.

When adding a new source, update it in a separate group and check its entries before replacing a working current server. Once you’ve confirmed the format, core support, and connection path, decide whether to include it in your regular rotation. If the source returns a client config rather than a server list, import it using the appropriate type. Repeatedly switching update options won’t force it to parse. Record format errors separately from network timeouts.

Match Update Schedules to the Scope of the Issue

Set a reasonable update schedule for each source and avoid repeated requests in a short period. Frequent updates won’t fix expired access credentials and may trigger source-side limits. On failure, update one group first instead of refreshing every source. A problem with one source usually doesn’t require changing system DNS or deleting other groups. If all sources fail at once, check the shared underlying network and update route.

Before updating, confirm which source provides the currently selected entry; afterward, check that the selection still exists. If the source removes an entry or changes its identifier, the client may keep the old selection, choose another entry, or require you to select one again. Check the list and logs to see what happened. “Update successful” means processing completed; it doesn’t guarantee the active entry changed to the new parameters, much less that the remote connection works.

Item to ManageRecommendedAvoid
Source groupsUse a clearly identified group for each sourceImporting the same URL into multiple groups
Manual experimentsKeep them in a separate manual groupEditing entries and expecting changes to survive a refresh
Troubleshooting updatesUpdate one source at a timeChanging all sources and outbounds at once
Config backupsStore them in a controlled local locationSharing exported files containing access credentials

Don’t Deduplicate by Note Alone

Entries with the same note aren’t necessarily identical; even entries with the same address and port may use different identities or security parameters. Before deduplicating, compare the protocol, address, port, user ID, transport, and security fields. Don’t manually delete every similar-looking entry just to tidy the list; the source may intentionally offer different connection options. If the client has a deduplication feature, find out which fields it compares and keep the original group as a fallback.

Test backup sources before the primary source fails. During a test, explicitly switch the current server and make a new request; selecting a row in the list may not set it as current. Multiple sources don’t provide automatic failover by themselves. Automatic selection or load balancing requires a supported mechanism, availability checks, and outbound configuration. Multiple groups don’t automatically form a failover pool.

When moving to another device, distinguish transferring subscription URLs from transferring the entire client configuration. A full export may include local listeners, routing, DNS, and device-specific options that won’t suit the new platform. It’s usually easier to import the sources first, then configure the entry point and routing for the new device. Check core support separately on desktop and Android; a protocol combination that works on one device may fail to start on another.

Review and remove expired sources periodically, but first check whether any routing rules, fixed outbounds, or manual tests depend on their entries. Before deleting a group, note its purpose and switch to a working server. If the source URL changes, update the existing group as instructed by the provider rather than creating more groups with the same name. For subscription update failures, return to the Subscription Groups section to check the URL and filters, then use Layer-by-Layer Troubleshooting to check the update path. Not every failure is a server problem.

Custom Outbounds

An outbound is how the core makes an actual connection; a routing tag is the reference name used to direct requests to it. Custom outbounds are useful when you need a fixed exit, selective blocking, or a connection through a local proxy. Most users can select a server and use a routing preset for basic needs. Edit the full config only when you can explain why an additional outbound is needed. The more settings you add, the more important startup checks and rollback notes become.

Confirm the Editor Accepts a Full Configuration

The server editor, routing editor, and custom config entry point in v2rayN handle different layers. The server form can’t accept arbitrary top-level JSON, and the routing editor won’t create an outbound for you. Before using a custom config, check whether the client loads the file directly or merges the snippet into its generated config. Files in the runtime directory may be regenerated at the next launch; use the client’s persistent configuration option rather than relying on an ad hoc edit.

This complete Xray example config listens only on the local machine. It provides a SOCKS entry point, uses direct routing by default, and blocks a specified test domain. It has no remote proxy server, so it can’t replace a subscription. Its purpose is to test the entry point, tags, and routing references. The port is just an example; if it’s already in use, change it in both the config and the test command. Don’t change the listen address to all network interfaces without access controls.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "domain": ["full:example.com"],
        "outboundTag": "block"
      }
    ]
  }
}

Tags, Default Outbound, and Complete References

Every outbound that needs to be referenced should have a clear, unique tag. The routing rule’s outboundTag must match an existing outbound. Differences in capitalization or extra spaces can cause config errors or unexpected behavior. Requests that match no rules usually use the first outbound, so changing the list order changes the default. Record the default and exception outbounds separately; that’s more reliable than noting only the rules.

A direct outbound means the core connects to the destination over the local network; it doesn’t mean the request skipped the client. A block outbound actively terminates matching traffic. To connect through another local SOCKS service, specify its listening address, port, and authentication method, and make sure it won’t send requests back to the current entry point. Using the same listening port as both the entry point and downstream outbound is a common loop; the two services also can’t bind to the same address and port.

Use the Server Configuration for Remote Parameters

A remote protocol outbound may need transport paths, service names, server names, public keys, or other parameters in addition to the address, port, and identity fields. Match every field to the server configuration; don’t combine values from different entries. REALITY is a transport security protocol, not something you enable by changing the protocol name to REALITY. For an explanation of its parameters, see REALITY Explained.

A protocol shown in the client doesn’t guarantee that the selected core supports every security and transport combination. Xray and V2Fly have different support, and v2rayNG and v2flyNG don’t use fully interchangeable fields either. Check the selected core before loading the config, then review the startup logs. If a field is unsupported, find out which implementation it belongs to rather than stripping security parameters until the config happens to start.

Chained proxies require checking how each hop connects and resolves DNS. The inner connection can’t use the outer outbound until it’s established. Timeouts, certificates, and address-family issues may also compound. First verify each outbound independently, then connect them using a chaining method supported by the core. Having two servers in the UI doesn’t mean they form a chain or that traffic automatically passes through them in list order.

Validate custom configs in stages: successful startup, a reachable entry point, then a single routing rule. Keep the working GUI configuration as a baseline. If an experiment fails, switch back to the baseline rather than adding more outbounds to a broken setup. In the logs, focus on protocol fields, tag references, and listener conflicts. Don’t share a complete file containing identity fields. Once these three parts work together, consider more complex outbound combinations; they’ll be easier to maintain.

Connection Checks and Rollback

Troubleshoot along the request path: app entry point, local core, DNS resolution, routing outbound, remote handshake, and target service. Different failures occur at different layers; calling all of them “a bad server” skips the easiest checks. Choose a stable, repeatable test target and record the client, core, entry mode, and current server before making changes. Change one variable at a time so you can tell what fixed the problem.

Start by Checking the Local Entry Point and Core Startup

If the core fails to start, the system proxy may already be set even though apps can’t reach the local listener. Check the logs for invalid fields, port conflicts, or missing permissions, then verify the listening address and port. The local port shown in the UI may differ from the one in a custom config; use the actual runtime config as the source of truth. Don’t test an HTTP proxy port as SOCKS: their handshakes differ, and using the wrong type may fail immediately.

Use this command to specify the SOCKS entry point explicitly and send DNS resolution through the proxy path. It applies only if the device has curl and the entry point uses the example port; it doesn’t test every app or TUN interception. If the connection is refused, check the local listener first. If the request reaches the proxy but fails, check routing and remote logs. The test domain is for a basic request and doesn’t imply that all destinations have the same network conditions.

curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 --max-time 20 -I https://example.com/

Separate DNS Failures from Handshake Failures

If the server hostname can’t be resolved, the remote handshake hasn’t started. Check basic DNS, the current network, and whether DNS resolution depends on the proxy it’s trying to establish. If the hostname resolves but the connection times out, check port reachability, firewall rules, and source status. A timeout doesn’t prove the protocol parameters are correct; it only means a wait didn’t finish in time. If the connection establishes and then closes immediately, check that protocol, security, and transport parameters match the server.

For certificate errors, check the system clock, server name, and certificate chain first. Don’t disable validation to hide the cause. When a transport uses a path or service name, capitalization, leading slashes, and spaces can affect matching. Check REALITY parameters against the source exactly; don’t borrow them from a similar entry. When sharing troubleshooting details, include only the error type and field names, and hide identities, address tokens, and other sensitive values.

Failure StageCommon CluesNext Step
Local entry pointConnection refused, listener failedCheck the port and core startup
DNS resolutionDomain lookup failedCheck the upstream and resolution loops
Remote connectionTimeout, connection closedCheck the port and transport parameters
Target requestOnly some services failCheck rules, outbound, and address family

Roll Back Complex Settings in Reverse Order

If the problem began after enabling a feature, undo that change first. For a complex setup, roll back step by step to a standard proxy baseline—for example, disable FakeDNS, then TUN, custom DNS, and custom routing—and retest after each change. After turning off FakeDNS, account for stale caches; after turning off TUN, confirm the system routes have been restored. Flipping the UI toggle back doesn’t necessarily clear the effects of existing connections and cached results.

Test subscription update failures separately from website access failures. If proxy requests work but subscriptions don’t, check the source URL, response content, and update method. If a subscription updates but the server won’t connect, a successful update doesn’t prove its connection parameters work. If several sources fail at once, investigate the shared entry point and underlying network. If only one entry fails, keep the working entries as a comparison instead of deleting every source.

When only some apps fail, compare their entry points, app-specific DNS, UDP use, and exclusion settings with those of working apps. A working website doesn’t prove UDP works, and a working system proxy doesn’t prove the virtual interface works. Existing long-lived app connections may still use the old outbound; reconnect before judging the result. For a fuller sequence of remote checks, see Node Timeout Troubleshooting Notes.

After fixing the problem, keep a short change log: the original symptom, the confirmed failure layer, what changed, and how you verified recovery. Restore the normal log level after temporary debugging to avoid accumulating records that contain destination addresses. If you can’t reproduce the problem, keep the stable baseline and don’t add unverified optimizations. To revisit the first-connection steps, go to Getting Started. To find installation options for another platform, visit the client downloads page. A configuration path you can explain, verify, and roll back is easier to maintain than one with more toggles.

Recommended Reading Order

Sources and entries → entry point and core → DNS and routing → traffic interception and custom outbounds. Start with a stable connection, add features one at a time, and return to the last working config if something breaks.

Back to Getting Started