Advanced · Config Reference

V2Ray Advanced Configuration Guide

Subscription groups, routing rules, DNS, and traffic interception.

For your first setup, follow the user guide to import a configuration, connect, and verify it. This page is a reference for after you’re connected: change one configuration layer at a time, then check the logs. Desktop instructions focus on v2rayN; Android differences are covered in the relevant sections.

Subscription Groups and Server Filters

Start by distinguishing subscription URLs, subscription groups, and server entries. A subscription URL is the source for fetching configurations. A subscription group is the client’s container for that source and its update settings. Server entries are the connection details retrieved after an update. These are three separate things. Deleting a server usually does not remove its subscription, so the entry may return on the next update. To retire a set of configurations permanently, disable updates for the relevant group first, then decide whether to delete the group and its entries.

Create a Group You Can Track

In v2rayN, open the subscription group settings, create a group, and enter a recognizable note and the full subscription URL. Save the changes. Use a note that identifies the source and purpose, such as “Work device” or “Temporary test”; never put access credentials in the note. Subscription URLs may contain access tokens, so copy the entire query string—but don’t include the full URL in screenshots or public logs. If the field contains leading or trailing spaces, remove them before saving so a formatting mistake isn’t mistaken for a network problem.

Update this group by itself first. Don’t judge success by whether a notification disappears: check that the log shows a completed request, the entry count changes as expected, and servers from the group appear in the list. Then select a known-working configuration as the active server and verify it using the quick-start steps. When updating multiple sources at once, a successful update from one group can obscure a failure in another. Avoid updating all groups when setting one up for the first time.

Set the automatic update interval according to how often the source changes. Very short intervals create unnecessary repeat requests and may trigger rate limits on the source. Sleep, network changes, and the app being closed can all affect scheduled tasks; an interval does not mean the server pushes updates to you. Before updating, check whether the subscription URL is reachable directly. If it can only be fetched through your current proxy, use the client’s proxy-based update option and keep one working active configuration so the update route and active connection don’t fail at the same time.

Filtering vs. Deleting Configurations

Server filters usually change what appears in the list; they don’t alter the server configurations themselves. Select a group before entering a name keyword to reduce the chance of acting on the wrong entries. Check whether name filtering, protocol filtering, or a specific-group-only view is enabled before concluding that an entry is missing. Some interfaces support regular expressions; others match plain text. Follow the field’s instructions. A plain-text keyword is not automatically a regular expression, and vice versa.

If the filter explicitly supports regular expressions, use Work|Backup to match either keyword or ^Test to match names starting with “Test.” Check the results before deleting anything in bulk. Parentheses, plus signs, and square brackets have special meanings in regex; if a source name contains them, escape them according to the interface’s regex rules. If you’re unsure which matching mode is in use, start with one plain-text keyword rather than a complex expression.

ActionScopeWhere to verify
Switch groupsCurrent list viewGroup label and list
Enter a filterVisible entriesCheck whether entries return after clearing it
Update subscriptionServer details from that sourceUpdate log
Set active serverDefault target for new connectionsActive indicator and connection log

Preserve the Evidence When an Update Fails

If the list is empty, clear the filter, switch back to the relevant group, and check the update log. For a connection timeout, investigate the network path; for a parsing error, inspect the response content. A subscription endpoint may return a sign-in page, an expiration notice, or an ordinary webpage. The request may succeed while the client still fails to recognize the page as server configuration data. Changing protocols repeatedly won’t help. Check whether the URL has expired or the source requires you to obtain a new subscription URL.

Before editing entries created by a subscription, copy them to a separate local group. An update may recreate entries and overwrite local changes. Keep the original group for syncing and the copied group for experiments, so you can return to the source settings during troubleshooting. Menus differ between v2rayNG and v2flyNG on Android, but the distinction between subscription updates and the currently selected server still applies. For common connection issues, see the Help Center. Don’t change DNS and routing at the same time if the subscription hasn’t imported successfully yet.

Routing Rules in Practice: Match Order

Routing sends requests that reach the core to an outbound; it doesn’t create connections for applications. First confirm that the request actually reaches the local proxy. Complete routing rules won’t change the path of an app that doesn’t use the system proxy. Troubleshoot in this order: application entry point, request metadata, rule match, outbound connection. Mixing up these four steps makes it easy to mistake an entry-point problem for a rule error.

Identify the Configuration Layer First

The v2rayN routing editor may use shorthand such as domain:example.com and geosite:private, or provide separate fields for domains and IPs. That’s how the client collects input; it doesn’t represent every field in the core’s JSON configuration. In the core, domains belong in the domain array and CIDR ranges in the ip array. Don’t paste an entire line from the interface into an arbitrary field. In particular, shorthand such as ip:192.168.0.0/16 is not a valid entry for the core’s IP array as written.

The routing snippet below can be merged into a V2Fly or compatible Xray configuration. It assumes outbounds named direct and proxy already exist. The first rule sends local addresses directly, the second routes the example domain through the proxy, and the last catches all other TCP and UDP requests. This demonstrates matching logic only; it doesn’t provide remote server details or work as a complete connection configuration on its own.

{
  "routing": {
    "domainStrategy": "AsIs",
    "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"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["domain:example.com"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

Put Exceptions Before the Catch-All Rule

Rules are generally evaluated in order, and the first match determines the outbound. A catch-all rule must come last; otherwise, later exceptions will never take effect. When a rule specifies a domain, port, and network type, those conditions generally all need to match. Multiple domains in the same array represent alternatives. Avoid combining unrelated requirements in one rule; separate rules are easier to inspect.

domain:example.com matches the domain and its subdomains; full:example.com matches the exact domain. Use regex only when names follow a clear pattern, not as the default. Domain rules don’t automatically match a user-entered IP address. To route an IP range the same way, add a separate IP condition and check whether the domain-resolution strategy allows lookups during routing.

AsIs doesn’t resolve domains just to evaluate IP rules. IPIfNonMatch tries to resolve the domain and then match IP rules if no domain rule matched. IPOnDemand may resolve it earlier when an IP condition requires it. These options affect lookup frequency and rule matching; they aren’t simple speed settings. Before choosing one, confirm that you need IP-based routing and that DNS queries can use the right outbound.

Verify the Match with One Request

To verify a rule, choose a domain you can identify with certainty, close any existing page or restart the target app, then make a new connection. Existing long-lived connections won’t switch routes just because you saved a rule. Temporarily increase log verbosity and check that the request’s destination, inbound tag, and outbound tag match your expectations. Restore your usual log level afterward. If you can see only an IP and not a domain, check whether the app passes the hostname and whether sniffing supports the protocol.

Geodata referenced by rules must be available to the current client and core. If you see an error about a missing data file or category, fix the data source first rather than changing rule order to hide a loading failure. The GUI’s routing setup may regenerate the configuration when the core restarts, so save rules in the client instead of making permanent edits to a temporary generated file. For how the fields fit together, see V2Ray Config JSON Structure Explained. Diagnose syntax errors separately from matching logic.

DNS Configuration and Resolution Paths

When troubleshooting DNS, distinguish three layers: the resolver used by the app or operating system, the proxy core’s resolver, and the remote service reached through the proxy. A browser with Secure DNS enabled may bypass the system resolver. An app that passes a domain to a SOCKS entry may leave resolution to the proxy. Changing a DNS address in the client doesn’t mean every program on the device will use it. First identify where a request becomes an IP address, then decide which setting to change.

Handle Server and Destination Domains Separately

If the proxy server itself is specified by domain, that domain must be resolved before the proxy connection can be established. Trying to resolve it through a proxy tunnel that hasn’t been established creates a dependency loop. The destination website’s domain can instead be resolved directly or through the proxy, depending on your routing needs. These domains serve different purposes; don’t use one vague “all remote DNS” setting for both. If the client can’t connect at all after startup, first check whether the server domain can be resolved through an independent path.

In v2rayN’s DNS settings, first confirm which core’s configuration you’re editing. Fields, defaults, and supported transport methods vary between backends; don’t paste JSON for one backend into another. This snippet illustrates built-in DNS settings in the V2Fly style: assign a static address to an example domain and ask a specified resolver for IPv4 addresses. It affects requests handled by that built-in resolver only; it doesn’t automatically take over system DNS.

{
  "dns": {
    "hosts": {
      "example.com": "192.0.2.10"
    },
    "servers": ["1.1.1.1"],
    "queryStrategy": "UseIPv4"
  }
}

The static address in this example is for documentation only, not a valid target for testing real website connectivity. Remove the example mapping or replace it with a domain you manage and its correct address. Static mappings are suitable for known, stable internal services, not content delivery services whose addresses change over time. The latter may return different results by region, network, or time, so pinning an address can cause connection failures.

Establish a Baseline Before Optimizing

Compare one change at a time: keep the same active server, routing setup, and test domain; change only the resolution path, then establish a new connection. If you change both the server and DNS, you won’t know which change helped. A system lookup tool proves only which resolution path that tool used, not that core DNS is working. Check the core logs alongside a real app request to see the query target, response type, and address used for the subsequent connection.

SymptomCheck firstCommon misdiagnosis
Server domain won’t resolveResolution path before startupThe proxy isn’t up yet
Only the browser worksBrowser Secure DNSSystem resolution may still be failing
Some domains resolve to the wrong addressStatic mappings and cacheExisting connections may still use the old address
Domain resolves, but connection failsRouting, outbound, and address familySuccessful resolution doesn’t guarantee reachability

IPv4 and IPv6 support must match the available egress path. If a lookup returns an IPv6 address but there’s no working IPv6 route through the exit, the app may wait for a failure before falling back, making DNS appear slow. Temporarily restricting queries to IPv4 can help isolate the issue, but it isn’t a universal fix. If your use case requires IPv6, check the local network, proxy server, core outbound, and routed address ranges—not just whether an AAAA response is returned.

Understand Encrypted DNS and Cache Boundaries

Encrypted DNS also requires checking the resolver’s connection path, certificate name, and bootstrap resolution. If the resolver is specified by domain, that domain still needs an initial lookup. Some special formats may send queries directly from the local system instead of following normal outbound routing. Behavior depends on the DNS types supported by the current core. Don’t assume a query goes through the active proxy just because its address starts with an encrypted protocol scheme.

After saving settings, the client, operating system, browser, and app’s long-lived connections may all retain old state. Start a new test connection, then clear the relevant cache if needed; there’s no need to reset the entire network every time. If the core log shows the correct address but the app still reaches an old destination, check the app’s cache. Under TUN, also confirm that DNS interception actually covers the request. A query that isn’t intercepted won’t change paths just because you edited the built-in DNS settings.

TUN Mode and Virtual Network Adapter Routing

A system proxy advertises a local proxy endpoint to apps; whether they use it depends on how each app is built. TUN uses a virtual network adapter and system routes to send eligible IP traffic through the processing chain. These have different entry points and aren’t simply weaker and stronger settings for the same switch. Consider TUN only after the regular system proxy works and you’ve confirmed that certain apps ignore proxy settings. That way, basic configuration problems don’t follow you into a more complex traffic-interception setup.

Check Permissions and Existing Routes First

Record your current routing setup, active server, and DNS settings first. Confirm that regular connections still work with TUN off. Then check for other VPNs, virtual network adapter tools, or traffic interception software that may already be running. When multiple tools compete for the default route, they may all appear enabled while traffic enters a different path. Use just one interception mechanism while testing. Confirm what each one handles before trying to run them together.

On Windows, creating a virtual adapter and changing routes typically requires administrator privileges. On macOS and Linux, system authorization or a service component may be needed. Follow the permission prompts in your current v2rayN interface; don’t repeatedly launch it without elevated privileges and judge success by the switch’s color. Permission failures, missing components, and configuration syntax errors are different issues—check the startup logs to identify which one occurred. For installation options, visit the client downloads page and match your operating system and processor architecture.

v2rayN may handle TUN through a separate traffic-interception backend rather than a generic field added to V2Fly or Xray JSON. Don’t assume that an arbitrary TUN snippet found online works with every core. Start with the options provided by the client so it can generate the configuration for the relevant backend. Edit advanced parameters only after confirming the backend type and where its configuration belongs.

Enable in Stages and Watch the Connection

After enabling TUN, check in order whether the virtual adapter was created, routes were added, DNS is being intercepted as expected, and the target app generates new connection logs. A lit switch means only that you requested activation; it doesn’t prove every step succeeded. Test a regular webpage first, then an app that previously ignored the system proxy. If even the webpage fails, turn TUN off and confirm the basic connection before changing MTU, the route table, and server settings all at once.

The proxy server’s own connection needs a valid outbound path and must not be intercepted back into the same proxy chain. Clients usually generate bypass or protection rules, but multiple adapters, mobile hotspots, and network changes can still affect interface selection. If logs show repeated connections, an unusually high connection count, or the server address repeatedly entering the interception chain, disable TUN first. Check how the server address is excluded and which interface is the default outbound; don’t just increase retry counts.

Local network exclusions must cover the networks you actually use—not just the common private ranges. Corporate networks, virtual machines, and containers may use other ranges or depend on specific interfaces. If something fails only after connecting to an office network, compare the routes before and after connecting. Allowing LAN devices to connect to this machine’s proxy is a separate feature involving a listening address and firewall settings; it isn’t enabled by the TUN switch. See Sharing a Proxy on Your Local Network for instructions.

Separate Protocol Support from Adapter Interception

TUN’s ability to receive a type of packet doesn’t mean the remote outbound can forward it successfully. UDP apps also depend on server configuration, transport, and network conditions. Some diagnostic tools use control messages that aren’t a reliable measure of proxy support for real workloads. Test the protocol your app actually needs and confirm the forwarding path in the logs; don’t treat one probe result as a complete picture of network health.

If some pages stall, check MTU only after verifying DNS, routing, and the UDP path. Large packets can encounter fragmentation or path discovery problems on some links, but blindly lowering MTU can hide the real cause. Record the original value, change one setting, and retest the same workload. Revert it if there’s no improvement. For a more detailed enable-and-rollback sequence, see Setting Up TUN Mode in v2rayN. Keeping a way back matters more than enabling every advanced option at once.

FakeDNS Mappings and Domain Recovery

FakeDNS returns a synthetic address, not the destination service’s real address. The proxy maintains a mapping from that address to the original domain. When the app connects to the synthetic address, the processing chain looks up the domain and then applies routing or connects remotely. This addresses cases where an entry point sees only an IP and needs to recover the domain for further handling. It isn’t just another name for DNS caching. Understanding that distinction helps determine whether your entry point needs it.

It Requires a Complete Mapping Chain

A working path needs at least four steps: the query reaches FakeDNS, the app receives a synthetic address, the connection returns to the handler that maintains the mapping, and the handler recovers the domain and selects an outbound. If any step is missing, the synthetic address may be sent over the network as an ordinary destination. Adding an address pool to the configuration alone won’t intercept queries or subsequent connections. First confirm that the client’s current backend actually supports this capability.

V2Fly-style FakeDNS configuration and synthetic address features in some TUN backends use different syntax. Despite similar names, they may differ in address pools, caching, persistence, and domain exclusions. Don’t combine a switch from one backend with an address pool from another. The snippet below shows how the address pool, DNS, and inbound sniffing fit together in a V2Fly configuration that supports this syntax. When merging it, preserve the complete outbounds and existing routing rules.

{
  "fakedns": [
    {
      "ipPool": "198.18.0.0/15",
      "poolSize": 65535
    }
  ],
  "dns": {
    "servers": ["fakedns"]
  },
  "inbounds": [
    {
      "tag": "local-socks",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["fakedns"]
      }
    }
  ]
}

This snippet doesn’t automatically send the operating system’s DNS queries to the core. If an app gets a real address from another resolver, the FakeDNS pool won’t be involved in that request. If the app gets a synthetic address but bypasses the proxy and connects directly, that will fail too. During testing, confirm that the query and connection use the same processing chain. Check the options in your client to confirm whether the current Xray or other backend supports these fields; this example isn’t proof of compatibility.

The Address Pool Is Not a Reachable Destination Network

Check the synthetic address pool against the network plan actually in use. Example ranges are commonly used for this type of mapping, but some test environments and internal networks may use them too. If ranges overlap, the system can’t distinguish a real service from a synthetic mapping based on the destination IP alone. Check the route table and internal network usage before choosing a pool supported by the backend. Don’t switch to a public address range just to avoid a conflict.

Pool capacity limits how many mappings can be maintained; it doesn’t limit simultaneous connections. Many domains, frequent network changes, or long-lived app caches can leave old addresses out of sync with current mappings. After restarting the core, an app may still hold an old synthetic address. Make it query again instead of retrying the stale connection. Clearing a browser tab may not clear the system cache, so target the layer that actually holds the cached value.

Some apps check whether a destination belongs to a special-purpose address range or store lookup results for a long time. They may not work well with synthetic addresses. To exclude a domain, use DNS rules that support this feature to return its real address, while ensuring its connection still follows the route you need. Excluding a domain from DNS synthesis is not the same as routing it directly: a connection to the real address can still use a proxy outbound.

Verify It Alongside Domain Routing

After enabling FakeDNS, test one domain. The logs should show the synthetic address being restored to its domain, followed by a match to the expected rule. If the synthetic address instead hits a generic IP rule, investigate the recovery step rather than forcing the entire address pool to use one outbound. Forwarding the pool may change what you observe temporarily, but it won’t restore the lost domain and may send a meaningless destination to the remote server.

If your SOCKS domain entry point already routes reliably by domain, FakeDNS may not add anything. It’s most useful when a connection arrives by IP and the domain must be recovered, with both queries and connections under control. After testing, document why it’s enabled, which entry points need it, excluded domains, and how to roll it back. Recheck after changing cores or interception backends; copying the old address pool alone doesn’t complete a migration.

Managing Multiple Subscriptions and Update Boundaries

Managing multiple subscriptions is about tracking sources and their purposes, not piling every server into one list. Use one base group per source, then a separate local group for manual experiments. If a source has different entry points for different tasks, note their purposes so similarly named groups aren’t updated twice by mistake. A clear group structure makes it possible to tell where an entry came from, why it changed, and which configuration should handle everyday connections.

Separate Synced Data from Local Changes

Server details returned by a subscription are maintained by the source. Local notes, ordering, and manual edits are client-side state. Whether updates preserve that state depends on how the client identifies entries; matching names don’t guarantee that it treats them as the same object. If a source changes a name, port, or identifier, the client may create a new entry. Copy important local changes into a manual group and record why you made them; leave the original group responsible for syncing.

Don’t remove duplicate-looking configurations based only on their display names. Two entries with the same name may use different ports, protocols, transports, or security settings; different names may point to the same endpoint. Before cleaning up, check the source, compare connection details, and consider their actual purpose. If the client has a deduplication feature, find out which fields it uses and export your settings before proceeding. Move uncertain entries into a test group before deleting them in bulk; that’s easier to undo.

Local groups and subscription groups should also have different update policies. A manual group doesn’t need a subscription URL; adding one can give the false impression that all its edits will be maintained automatically. If a subscription update changes protocol parameters, first verify the updated server in the original group, then decide whether to migrate your local test entries. Don’t overwrite source entries with old parameters; the next update will conflict with those changes again.

Plan Update Order and Fallbacks

First determine whether at least one source can be updated directly on your current network or whether they all depend on a proxy. If updates require a proxy, your active server can affect the result. For routine updates, handle groups one at a time: update an inactive source first, verify that it works, then update the current source. This reduces the chance that the active connection and configuration change at once, and gives you a working baseline if a group returns an unexpected response.

Group typePrimary roleRecommended approach
Source sync groupStore the subscription and original entriesUpdate regularly; avoid manual edits
Local test groupTest transport or parameter changesRecord changes and maintain manually
Independent backup sourceProvide an alternative update pathTest separately; don’t rely on names alone
Retired sourceKeep a record for migrationStop updates; delete after confirming

Multiple subscriptions don’t provide automatic failover. A regular group is just a way to organize configurations, and switching the active server often still requires user action. Expect automatic outbound selection only when you’ve explicitly configured a client-supported selection or scheduling mechanism. Verify its health-check conditions separately. Multiple server entries in the list don’t mean the core will automatically try another one when a connection fails.

Speed test results don’t determine long-term priority on their own. Establishing a connection, loading a webpage, and sustained transfers measure different things, and the test target affects the result. Choose a test that reflects your use case and compare results under the same conditions. Keep the network, routing, and DNS unchanged during testing so you don’t attribute network changes to a subscription source. If a configuration fails, check whether it requires a protocol or transport capability that isn’t enabled yet.

Migrate Settings and Protect Subscription URLs

Before moving to another computer, check separately whether the export includes client settings, subscription URLs, and locally maintained servers. Some exports include servers but omit routing, DNS, or interception settings. After importing, inspect each area rather than enabling TUN just because all the entries are present. Verify the regular proxy first, restore routing next, and restore advanced interception last. That keeps migration issues within a clearly defined layer.

Subscription URLs can grant access and should be stored as sensitive configuration. When sharing troubleshooting details, keep the error type and status but redact the full URL, account parameters, and server credentials. If you suspect a URL has been exposed, generate a new one at the source and update the client; changing the group note won’t help. After deleting a retired source, check for old entries copied into a local group so they aren’t selected by mistake later.

If several sources fail to update at once, check shared dependencies first: system time, DNS, current network, proxy-based update path, and local firewall. If only one source fails, focus on its URL and response. This order prevents you from blaming each subscription separately for a global issue. If a browser can reach the source but the client can’t update, compare their proxy and resolution paths. A working browser doesn’t rule out a local configuration problem.

Custom Outbounds and End-to-End Configuration Checks

An outbound defines how the core sends a request to the next hop; routing selects which outbound to use. Custom outbounds are useful for specialized upstreams, fixed local forwarding chains, or explicitly chained connections—not required for importing an ordinary subscription. Before starting, keep a verified standard configuration in v2rayN and identify whether you’re using a client-managed server, a complete custom configuration, or a mergeable configuration snippet. Each has different rules for field overrides and saving.

Connect Inbounds, Rules, and Outbounds with Tags

tag is an internal configuration name. A routing rule’s outboundTag must exactly match the tag of an existing outbound, including capitalization and spelling. Use a short name that describes its purpose; don’t put server passwords or full addresses in a tag. Missing or duplicate tags, or references to nonexistent objects, can prevent startup or send traffic through an unexpected outbound.

This is a standalone local forwarding example using a common V2Fly and compatible Xray structure. It exposes a SOCKS inbound on the loopback address and forwards all traffic to another SOCKS service on the same machine. A separate upstream must already be listening on port 20808. Without it, the snippet can still help you check the configuration structure, but connections will fail. It contains no remote server credentials and can’t replace a working configuration from a subscription.

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "local-in",
      "listen": "127.0.0.1",
      "port": 10818,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": false
      }
    }
  ],
  "outbounds": [
    {
      "tag": "upstream-socks",
      "protocol": "socks",
      "settings": {
        "servers": [
          {
            "address": "127.0.0.1",
            "port": 20808
          }
        ]
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "network": "tcp",
        "outboundTag": "upstream-socks"
      }
    ]
  }
}

UDP is disabled in this example to keep the test focused on TCP and avoid assumptions about upstream UDP support. The listener is bound to the loopback interface for local use only. Don’t expose it on every network interface just to make testing easier. If you need to share it, configure source restrictions, authentication, and firewall rules separately. Its port must also be free of conflicts with existing client listeners; a conflict causes startup failure, regardless of remote connectivity.

Prevent Loops in Chained Connections

The most common forwarding-chain mistakes are pointing an entry back to itself or routing the upstream through the system proxy back to the current entry. Before configuring the chain, map out the exact order: application, local inbound, selected outbound, independent upstream, final destination. Record the listening address and port at every hop; “use a proxy” isn’t specific enough. If the upstream also uses TUN, make sure connections to its server aren’t intercepted again by the downstream setup.

Be clear about which hop resolves domains. If an app passes a domain, the upstream SOCKS service may resolve it. If the app passes an IP, later hops generally have only that address unless a reliable recovery mechanism is in place. An outbound chain won’t correct a failed lookup or give an upstream support for a transport it doesn’t handle. When testing a chain, verify the upstream works on its own before adding downstream forwarding.

A complete custom configuration may bypass some routing and DNS settings generated by the client. Before saving, read the interface guidance and confirm that the system proxy entry still points to the actual listening port. Don’t assume that changing routing in the GUI also updates the custom configuration. Conversely, a temporary generated file may be overwritten on the next startup. Maintain long-term changes in a configuration entry officially supported by the client, and keep the original file as a fallback.

Verify the Configuration, Entry Point, Routing, and Exit

Check JSON syntax first, then confirm that the core supports each field. Valid JSON means the brackets, commas, and strings are correctly formed; it doesn’t mean the configuration is semantically valid. If startup logs report an unknown protocol, missing tag, or port conflict, fix that local issue first. Once the core starts reliably, make a request from one app and check whether the inbound receives it, routing selects the expected outbound, and the upstream accepts the connection.

If a browser works but a terminal doesn’t, first check whether the terminal is actually using the local entry point instead of changing the outbound again. Some terminal apps require proxy environment variables or command-line options; the system proxy doesn’t configure all of them. For troubleshooting steps, see System Proxy Not Working: Troubleshooting Browsers and Terminals. Test each change with a new connection; an existing session may still use the old outbound.

Record four results at the end: whether the configuration loads, which rule handles the target request, which outbound it uses, and whether connections recover when advanced features are disabled. Then separately test subscription updates, local network access, and any UDP workloads you need; don’t stop after checking one webpage. Restore your usual log level and remove temporary rules and unnecessary entry points. Repeat the same checks after changing clients or cores—a configuration that imports successfully doesn’t guarantee identical behavior.