In-depth guide · v2rayN desktop configuration

v2rayN
Advanced Configuration Guide

Configure subscriptions, routing and traffic handling in stages. Keep a working baseline, then change one variable at a time.

For your first installation, subscription import and connection, follow the quick-start guide. This page is a reference for after you connect: it explains how settings interact and provides configuration examples, validation methods and recovery steps. You don't need to read both pages in order; jump to the relevant section whenever a specific issue comes up.

The interface instructions below focus on v2rayN. Menu locations may change as the interface evolves. Code examples identify the supported core; Xray, V2Fly and sing-box configuration formats are not interchangeable. Snippets are meant to be merged into the appropriate configuration section, not used as standalone configuration files.

Subscription Groups and Server Filtering

Subscription groups track where configurations come from; server filters narrow down the list. Neither improves server-side connection quality or replaces routing. Start by putting one subscription URL in a clearly named group. Update it, confirm the servers appear, then add filters. If you create a group, change the URL and enable a regex all at once, an empty list makes it hard to tell which step went wrong.

Create a group and set its update source

In v2rayN's subscription group settings, create a group and enter a recognizable note and subscription URL. Save, return to the main window, select the group and update its subscription. Keep the URL exactly as provided, including its path and query parameters. When copying from a chat app, check for stray quotes, line breaks or a period at the end. Subscription URLs often contain access credentials; don't share the full URL in screenshots, logs or public discussions.

The “Through proxy” and “Direct” update options control only how the subscription request is sent. They don't route every server in the downloaded list. If your current proxy isn't connected, forcing updates through it can create a dependency loop: you need the new configuration to connect, but need a connection to download that configuration. Try an update path you can reach first, then decide whether to change the method for future updates.

After saving, check three things: the group note is correct, the subscription URL is intact, and the update log shows that valid content was parsed. A successful request with no change to the list doesn't necessarily mean the client failed; the remote server may have returned the same content, a login page or explanatory text. Don't rely only on the completion message. Check the parse results and target group too, and temporarily disable filters if needed.

Start with simple regex patterns

“Server filter (regex)” typically matches server remarks. Whether it applies during import or only to the displayed list depends on the current interface. Test a short fragment from a name you can see, then add alternatives if needed. Don't start with a complex exclusion pattern. In a regex, a vertical bar means “or,” parentheses group expressions, and square brackets define a character class; none of these symbols is ordinary text punctuation.

Hong Kong|Japan
^(Hong Kong|Japan)
Hong Kong.*dedicated
\[Backup\]

These four lines are separate examples; don't paste them all into one field. The first matches remarks containing either keyword; the second requires a remark to start with one of them; the third looks for both fragments in order; the fourth matches text enclosed in square brackets. If a provider uses different abbreviations, these patterns may return no results. Base filters on the actual remarks rather than treating region names as a universal convention across subscriptions.

If the pattern is invalid, clear the regex and save first. Confirm the servers reappear, then restore the expression piece by piece. Characters such as periods, parentheses and plus signs have special meanings; to match a literal period, for example, use \.. Regex support may differ between client builds, especially for lookarounds, inline options and complex groups. Short, readable patterns are more reliable than advanced syntax that may not work everywhere.

Tell a filter problem from an update failure

If servers disappear after filtering, switch to “All” or the relevant source group, clear the search box and check the group filter. The main-window search and subscription filters may stack, so changing just one may not make everything visible again. Once you've found the filter causing the issue, decide which conditions to keep. Don't repeatedly delete the whole group to restore the list; that may also remove its note, update method and other settings.

For update failures, check the URL, request path, response content and parse format—in that order. If the same URL works over one network path but not another, start with the connection and DNS. If the response is a web page rather than subscription content, check that the URL is intended for subscriptions and that access is authorized. If already imported servers still work, keep the current configuration while troubleshooting instead of turning an update issue into a complete loss of connectivity.

Routing Rules in Practice

Routing is based on ordered matching: the core checks the connection destination and available metadata, then selects an outbound when a rule matches. More specific rules generally belong before broader ones. Before editing, check which routing preset is active and whether the client regenerates the core configuration at startup. Changes to a temporary generated file may be overwritten when you switch servers or restart the core; they aren't persistent settings.

Choose outbound tags before writing conditions

The examples below use Xray's routing object format to block ad domains, send private addresses direct and send a specified domain group direct. They assume the complete configuration defines outbounds tagged direct and block. If the client generates different tags, update the references to match. Tags are exact identifiers, not reserved names whose meaning is inferred. Don't paste this object into a field that accepts only an array of rules.

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "domain": ["geosite:category-ads-all"],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["geosite:cn"],
        "outboundTag": "direct"
      }
    ]
  }
}

Different condition types within one rule usually all need to match, while multiple options in the same array are alternatives. For example, setting both domain and port means the domain and port must both match—not that either condition is enough. To match either a domain or an IP range, use two separate rules. Then check their order so a broader rule doesn't take the connection first.

What happens to traffic that matches no rule depends on the core's default behavior and the complete configuration generated by the client; this snippet alone can't tell you whether it will use a proxy. Xray typically sends unmatched traffic to the first outbound, but a graphical client may add fallback rules. Check the final outbound order and last rules before deciding whether to add an explicit default route. Review the full configuration, including its beginning and end, not just the lines you added.

How domains, IPs and rule databases fit together

geosite contains domain categories; geoip contains IP address categories. Both depend on the core being able to read the relevant data files and on those files containing the category names you use. A file being present doesn't mean every source includes the same categories, and a plausible-looking name won't create one. If a category fails to load, check the data file's source, location and core logs instead of repeatedly switching servers to fix a rule database issue.

domainStrategy determines whether routing performs DNS lookups to get IP information for domain matching. AsIs doesn't resolve domains just for IP rules; IPIfNonMatch tries to resolve a domain when no domain rule matches; IPOnDemand may resolve it when an IP-based match requires it. These settings change when lookups happen and how much work they require; they don't directly choose which DNS server handles a connection.

If an app sends only an IP address to the proxy, the core may not know the original domain, leaving domain rules with nothing to match. Sniffing can recover domain information for some traffic, but it can't reveal every encrypted connection or identify every protocol. If the same site takes different routes in different apps, first check whether the inbound connection contains a domain or an IP, then review sniffing and DNS. Don't start by expanding all direct or proxy rules.

Test rules with clear, explainable cases

For testing, choose one domain explicitly covered by a rule, one private-address destination and one destination with no matching rule. Open a new connection to each, then check the logs for the destination and outbound tag to confirm the expected rule order. Browsers may reuse existing connections, so refreshing after a rule change may not trigger a new route. Close the relevant connections or restart the test app before comparing results. A rule loading successfully and a request succeeding are separate outcomes; check both.

If a rule unexpectedly overrides others, temporarily remove the broadest match and test with the smallest possible rule set. Port, network-type and process rules can also affect results, especially when client-generated and custom rules are combined. For data file updates and category syntax, see Routing with geoip.dat and geosite.dat. Test the same set of destinations before and after updating.

DNS Configuration

Start with three questions: who sends the query, where does it go, and who uses the result? The system resolver, browser secure DNS, the client's built-in DNS and the core's lookups for routing may all be active at once. Entering a server address in the client doesn't guarantee that every app will use it. Aim for a consistent path, usable results and diagnosable failures—not enabling every available option.

Separate the DNS server from the query's outbound route

This Xray dns object snippet shows the server list and query strategy. queryStrategy controls which address types this built-in DNS query requests; it doesn't disable IPv6 across the system. The encrypted DNS endpoint in the example is just an option to test. Check that it's reachable on your network before adopting it. The snippet doesn't include DNS traffic routing, so it doesn't prove that queries will go through a proxy.

{
  "dns": {
    "servers": [
      "https://1.1.1.1/dns-query"
    ],
    "queryStrategy": "UseIP"
  }
}

Choosing a DNS server address and choosing an outbound for DNS queries are separate decisions. Some cores route encrypted DNS requests internally; other server types may use the local connection directly. The client may also offer separate options for direct DNS, remote DNS or a dedicated outbound. These labels describe the client's interface, not fields that map directly to another core's configuration. Identify the core in use and consult its documentation to interpret the generated configuration.

Encrypted DNS endpoints specified by hostname also need bootstrap resolution: the system has to find the DNS service's IP address before it can connect. If bootstrap resolution depends on a proxy that isn't connected yet, you can end up with a dependency loop. A fixed service address, an explicit bootstrap path or a client-provided startup resolver may solve the problem. Choose one approach you can explain rather than adding several servers with unclear roles.

Match DNS strategy to the connection path

Direct destinations generally need addresses reachable on the current network, and DNS for proxied destinations should work with the proxy's connection behavior. Some protocols send the domain to the server for resolution, so local DNS may be used only for routing decisions. Other paths resolve locally before connecting to an IP. If routing uses one result while the connection uses another, actual access may differ from expectations; check how the domain is preserved along the way.

SettingWhat it doesWhat it doesn't tell you
Built-in DNS serversProvide results for core-related lookupsEvery app uses them
Routing domainStrategyControls whether domains are resolved for matchingSystem DNS has been replaced
Query strategyControls the address types requestedSystem IPv6 is disabled
TUN DNS handlingReceives DNS traffic within its matching scopeApp-level encrypted DNS is always intercepted

For IPv6 issues, first check whether the network has a working IPv6 path, then choose an address preference. An AAAA record isn't an error by itself; the problem occurs when an app selects an address it can't reach and hangs or falls back. Temporarily requesting only IPv4 can be a useful comparison, but it isn't a permanent fix for every network. Also check that the proxy server, direct connection and TUN use consistent IPv6 settings.

A browser's secure DNS setting may bypass the system's usual resolver. Apps that query over an established encrypted connection may also not show up as ordinary DNS traffic. During troubleshooting, note these settings and temporarily use a consistent resolver path. Once the client path works, restore app settings one at a time and compare. Don't reset all system network settings at once; even if access returns, you won't know which change fixed it.

Check resolution, connectivity and routing—in that order

First check the logs to confirm the query reached the intended resolver. Then verify that it returned a usable address and that the connection used the intended outbound. A system DNS result from the command line describes only the system resolver; it doesn't represent the browser's own resolver or the core's internal DNS. Record the test app, destination domain, proxy mode and time so results from different paths aren't compared as if they were the same.

After changing DNS, old caches and connection pools may keep using previous results. Close the test app and clear the relevant cache; restart the client core if necessary, then test the same destination again. If only one domain fails, start with its routing rule and DNS response. If all domains fail but IP connections work, check resolver reachability and the bootstrap path. Don't add FakeDNS until regular connections are stable.

TUN Mode

TUN receives IP traffic routed through a virtual network interface and passes it to components associated with the client. Unlike the system proxy, which relies on apps honoring proxy settings, TUN operates closer to the network layer. But routing rules, exclusions, address families and permissions still determine which connections it handles. An enabled “TUN” toggle only means the client is trying to start the feature; it doesn't prove that all traffic is being handled as expected.

Get a regular connection working before expanding traffic capture

Before enabling TUN, turn it off and confirm that a normal system-proxy connection works with the selected server and basic protocol settings. Note the current routing preset, system DNS and status of other networking tools. Desktop clients may use a separate component or configuration structure for TUN. The fact that the main connection uses Xray doesn't mean you can paste Xray routing fields into another component's TUN settings. Start with the fields supported by the client interface.

The first time you enable TUN, follow the system prompts to grant the required permissions. Wait for the virtual interface and routes to be installed before launching a test app. Don't toggle it rapidly; turning it back on immediately after a startup failure can leave old processes or interface state in the way. Check the startup logs for permission errors, interface creation failures or address conflicts before trying again. When drivers or system services are involved, closing the interface doesn't necessarily stop the background component.

PlatformCheck firstCommon limitations
WindowsRequired permissions, virtual interface and routing tableOther virtual adapters and security software can interfere
macOSNetwork permissions and component startup statusHow permissions are granted varies by implementation; don't repeatedly approve prompts without checking
LinuxTUN device permissions, routing and firewallNetwork management services may rewrite routes or DNS
Androidv2rayNG VPN permission and app scopeVpnService differs from desktop TUN in interface and permissions

Prevent loops and keep LAN access

When system traffic is captured, the client's outer connection to the proxy server must still reach the network. It must not be sent back through the client's own capture rules indefinitely. Clients typically handle this with server-address bypasses, process exclusions or interface binding, but custom routes and proxy chains can break those safeguards. If all connections stop as soon as TUN starts, check for an outer-connection loop before assuming the server settings changed.

Test LAN services separately. Printers, router admin pages and local development servers may use private IPs or get their addresses through LAN name resolution. Sending private IPs direct may not fix local name discovery; check whether the relevant queries, broadcasts or multicasts are captured by the implementation. Don't exclude broad subnets just to reach one LAN device; use the narrowest range you actually need.

“Allow connections from the LAN” is not the same switch as TUN. The first usually controls the proxy's listening address and whether other devices can connect to a local port; the second captures traffic from this device. If other devices don't need to use this device as a proxy, there's no need to expand the listening scope. If they do, also check firewall rules, authentication and trusted-network boundaries so the proxy port isn't exposed on unnecessary interfaces.

For UDP to work, app traffic must be within the capture scope, the relevant client component must support it, and the selected protocol and server path must allow it. A real-time app failing doesn't necessarily point to DNS; UDP forwarding, destination ports or network restrictions may be responsible. Confirm the basic path with a regular webpage first, then test UDP with an app you actually use. Don't treat a TCP-only test as proof that everything works.

Find conflicts and restore settings layer by layer

Other VPNs, virtual machines, container networks and enterprise networking tools may all change routes or DNS. During troubleshooting, use one traffic-capture tool at a time. Stop other capture features before considering uninstalling software. Note whether the issue appears or disappears when a particular interface is enabled or disabled, and record interface and subnet details. If TUN stops working after sleep, a Wi-Fi change or switching to Ethernet, check whether it selected the correct outbound interface again.

To restore the previous state, turn off TUN, confirm the background component has exited, then check that system proxy, DNS and default routes are back as expected. If regular networking still fails, restore the original values you recorded in the system network settings. Don't reset the entire network as a first step. For macOS permission issues, see Installation approval and network permissions; for Android background interruptions, check the app's battery settings separately.

FakeDNS

FakeDNS returns synthetic addresses instead of real DNS results and stores a mapping from each synthetic address to its domain. When an app connects to one of these addresses, the core uses the mapping to recover the domain, then handles routing or proxying. This preserves domain information and can avoid some preliminary lookups; it does not provide a real server address that can be reached over the public internet. Understanding the difference helps explain why a connection can fail immediately when it bypasses traffic capture.

Make sure DNS and connections use the same path

For FakeDNS to work, the component that returns synthetic responses and the one that handles subsequent connections must share the mapping. If one component handles DNS while another handles connections without access to the mapping, all that's left is an unreachable synthetic address. Desktop clients may use different cores in different modes, so check the implementation before switching. Two settings called FakeDNS don't necessarily use the same configuration format or keep mappings for the same length of time.

The snippet below shows the relevant Xray fields: an address pool, a setting that enables FakeDNS for built-in DNS, and a sniffing override for a specified inbound. Merge each part into the matching section of the complete configuration. In particular, don't replace the entire inbound object with the snippet; existing fields such as its listen address, port and protocol must remain. These fields work together only when the full configuration path is connected.

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

Example sniffing settings for the corresponding inbound:

{
  "sniffing": {
    "enabled": true,
    "destOverride": ["fakedns"]
  }
}

ipPool defines the synthetic address pool, and poolSize limits the number of mappings. The example address range is for testing, not a regular public destination. Before using it, check whether a virtual machine, lab network or corporate network already uses the same range. If it conflicts, plan another range supported by the core and check the capture routes too; changing the address-pool string alone isn't enough.

Handle caches, lost mappings and app compatibility

Mappings usually exist only in the running core's state. After a core restart, an app may still have an old synthetic address cached, while the new instance has no record of its original domain. This can make some apps fail right after a restart and recover when their caches are cleared. When enabling or disabling FakeDNS, account for system DNS caches, browser caches and persistent connections. Restart test apps in order so stale cache entries aren't mistaken for routing errors.

Some apps validate address types, cache DNS results or pass addresses to another process. Synthetic addresses can cause problems in these workflows. LAN names, device discovery and some IP-based services may also be poor candidates for FakeDNS. If only one app has an issue, compare it with real DNS first, then consider excluding a domain or app. Use the syntax and exclusion point supported by the DNS component in question.

A rule that sends the synthetic address range directly to the system network may bypass traffic capture before the domain is recovered. Conversely, adding a proxy rule for synthetic addresses may not help if the core restores the original domain before matching. Check the final destination shown in the logs, determine whether your implementation restores or matches first, then adjust the rule. Don't apply rules for real IPs to synthetic addresses without checking the difference.

Compare with FakeDNS on and off

For a fair comparison, keep the server, routing preset and test app unchanged; toggle only FakeDNS. First confirm that the target domain receives a synthetic address. Then check whether the subsequent connection is restored to a domain and whether it uses the expected outbound. If there is no synthetic result, the app may be bypassing that DNS path. If there is one but the connection fails, focus on capture scope, mapping and inbound restoration—not on trying more DNS servers.

To turn FakeDNS off, first stop the app from opening new connections, then disable the feature and clear old caches before testing real DNS again. FakeDNS isn't required for every setup; if regular DNS and routing meet your needs, leave them as they are. Use FakeDNS only when you need to preserve domain information and can maintain the entire traffic-capture path. If a failure is hard to explain, switching back to real DNS is often the most useful first comparison.

Manage Multiple Subscriptions

Managing multiple subscriptions isn't about putting every source in one list; it's about keeping each source connected to its update method and purpose. Create a separate group for each source and use a note to explain its purpose. You can use your own naming scheme for work, home or testing, but don't put passwords, account details or full subscription URLs in group names. Write notes that will still make sense weeks later, not just on import day.

Track sources and set a sensible update schedule

For each group, record its purpose, update method and filter conditions. Keep these notes on your own device. Set automatic updates according to your needs and the provider's limits; don't make frequent requests just to keep the list looking fresh. More requests don't improve subscription content, and repeated refreshes may trigger rate limits. If an update fails, keep the last working configuration while troubleshooting that group instead of changing every source.

When organizing subscriptions for the first time, update one group at a time. Confirm each source can be fetched and parsed independently before trying bulk updates. This makes it easier to spot a broken URL or a group that needs a different request path. If only some groups fail in a bulk update, check their responses and access status before changing global DNS or proxy settings. Global changes can disrupt groups that were already working and make the problem harder to isolate.

A source may offer several format-specific URLs, and you can't tell whether they return the same content just by looking at them. Choose an endpoint compatible with the client and keep any required parameters. Don't confuse a web dashboard URL with a subscription URL. If the URL requires login or has expired, repeated retries in the client won't restore access. Get a valid endpoint through the provider's usual account interface instead of guessing at URL paths.

Distinguish duplicate names, duplicate configurations and the selected server

A server remark isn't a unique identifier. Two sources can use the same remark for different servers, and a server may look like a new entry after its remark changes. To check for duplicates, compare the actual protocol, address, port and identity parameters locally; don't delete entries based on names alone. The client may use its own criteria for deduplication, so check what the action affects before proceeding. Export your current settings first if you need a way to recover deleted entries.

A subscription update may replace server entries or change their order and remarks. Whether the selected entry remains selected depends on how the client matches old and new configurations; don't assume it always stays the same. After a major update, check the current group and selected server before resuming normal use. If the provider removed the previous entry, select an available one rather than assuming the same list position points to the same destination.

The provider usually manages subscription entries, and manual edits may be overwritten by the next update. If you need custom settings to persist, keep them in a clearly separate manual group and note why they were changed. Don't duplicate the same server across several groups without explaining their purpose; that makes it easy to edit the wrong entry. Knowing where a configuration came from matters more than giving its remark an elaborate name.

Migration, backups and privacy

Before moving to another device, decide whether you need to transfer client settings, subscription sources or a single server configuration. Export options include different information, and QR codes or share links may contain full connection credentials. Transfer them only through trusted channels and remove unnecessary temporary copies afterward. When asking for help publicly, share a redacted settings summary instead of a full export. Subscription paths and query parameters in logs also need to be removed.

Desktop v2rayN and the Android apps v2rayNG and v2flyNG can import compatible subscription content, but group settings, routing presets and app scope in the graphical interface won't necessarily transfer with it. Reconfigure and verify custom routing and DNS on the new device using its own core. See the client downloads to choose an installer; don't rely on the old device's filename to identify the new device's architecture.

Android background disconnections may come from battery restrictions rather than subscription conflicts. First confirm the connection works while the app is in the foreground, then check VPN permission, per-app scope and background limits. See Per-app proxy settings and battery optimization for v2rayNG for related steps. As part of regular maintenance, remove sources you've confirmed are no longer valid and keep useful notes so the list stays relevant to your needs.

Custom Outbounds

Custom outbounds let you define connection paths that aren't available in the client's standard interface—for example, sending selected destinations to another proxy listening on the same machine. This involves outbound protocols, tag references, listener reachability and loop prevention; it's more than adding a rule. Before editing, map which inbound receives the app traffic, which tag the rule selects and where that tag connects. Avoid adding multiple custom forwarding layers until you understand the regular proxy path.

Start with a minimal local SOCKS outbound

These Xray-format examples define three outbounds: direct, block and a connection to a local SOCKS service. Merge them into the outbounds array in the complete configuration. Don't replace the existing array blindly; you could remove the current server outbound or change the default order. The local address identifies the connection destination, and the port must match the running service. Without a listener at that address, the configuration may load but forwarding will fail.

[
  {
    "tag": "direct",
    "protocol": "freedom",
    "settings": {}
  },
  {
    "tag": "block",
    "protocol": "blackhole",
    "settings": {}
  },
  {
    "tag": "local-socks",
    "protocol": "socks",
    "settings": {
      "servers": [
        {
          "address": "127.0.0.1",
          "port": 1080
        }
      ]
    }
  }
]

This example has no authentication and is suitable only if the target listener is configured to accept the connection as intended. If the service requires authentication, use the user fields supported by the core and keep real credentials on your device. Don't widen the listening scope or disable existing authentication just to simplify setup. A loopback address refers to the network environment where the core runs; if the core is in a container or isolated environment, it may not point to a service on the host.

After setting up the outbound, add one specific test rule. The reserved example domain below illustrates how to reference a tag; it isn't expected to serve real traffic. For testing, use a destination you actually need to check and keep the rule in the right position. outboundTag must match the outbound's tag exactly, including capitalization, hyphens and spelling.

{
  "type": "field",
  "domain": ["full:example.com"],
  "outboundTag": "local-socks"
}

Forwarding is not the same as proxy chaining

Sending an app connection to a local SOCKS service means that service handles the next connection; it doesn't mean the proxy servers are automatically chained in a particular order. A real proxy chain needs explicit settings for how the outer connection is dialed, where domains are resolved and how each hop authenticates. Chaining fields differ between cores. Don't copy sing-box field names into Xray configuration or assume similar names have identical behavior.

One of the most dangerous mistakes is making two proxy setups point back to each other: client A sends a request to B, whose upstream points back to A, or TUN sends the proxy's outer connection back to the original inbound. Trace the path backward from the final destination. Make sure every hop can reach the next and that the chain has a clear endpoint. First turn off TUN and verify the custom outbound with a single app proxy, then restore system-level traffic capture in stages to narrow down problems.

Multiple outbounds can also make DNS and UDP behavior less predictable. A local SOCKS service that handles TCP may not support the UDP forwarding you need. Whether the first or next hop resolves a domain also affects routing and reachability. Test domain destinations, IP destinations and the actual app protocol separately; a successful connection to a port doesn't prove the entire chain works.

Save, verify and roll back

Prefer the client's own entry for custom configuration, outbounds or routing. Some fields accept a complete configuration; others accept only an object snippet. Check the interface instructions and existing structure before pasting. JSON objects, arrays and strings must remain valid; don't add comments or trailing commas. Duplicate tags, references to missing tags and arrays placed in object fields can prevent startup or silently override other settings.

After saving, check whether the core loaded successfully, then open a new connection and confirm that the outbound tag in the logs matches the intended listener. If loading fails, restore the previous configuration before changing servers or updating subscriptions. If loading succeeds but the connection is refused, check that the local service is running and its address and port are correct. If the connection is established but still fails, check the next hop's protocol, authentication and DNS.

Once the setup works, record its purpose, dependencies, listening port and rollback steps so you remember to start the upstream service next time. For more about how cores relate to clients, see Project V, V2Fly and the Xray ecosystem. For issues that span several topics, search Frequently Asked Questions by symptom. Keep a working system-proxy baseline and return to that simplest path first if a custom outbound fails.