JSON Structure Overview
A configuration file describes how the core handles connections; it is not a copy of every option in the client interface. Read it along the data path: an app sends a connection to an inbound, routing selects an outbound based on its destination and source, and the outbound connects directly to the destination or to a remote service. DNS supplies results where needed, while policy controls connection timeouts and statistics. Objects are linked by values such as tags and user levels, so an isolated snippet rarely explains the full behavior.
First, distinguish client settings from the runtime configuration
v2rayN subscription groups, interface preferences and update settings do not necessarily belong in the core JSON. The client typically generates a runtime configuration from the selected server, routing template and other options, and may regenerate it when reconnecting. Direct edits to a generated file can be overwritten the next time you switch servers. First identify where a setting comes from: change ordinary port and routing options in the interface, and use the client's import or custom-configuration feature when you need a fully custom setup.
This page uses the common object-based V2Ray JSON format as its reference and does not treat extensions from different cores as one shared standard. v2rayNG uses the Xray core, while v2flyNG uses the V2Fly core; v2rayN's capabilities depend on the core currently selected. The same field name may accept different values, and some newer transports are not supported by every core. When you encounter an unknown field, first check the active core and configuration format instead of deleting nearby fields one by one.
A minimal local direct-connection setup that runs
The complete configuration below creates two inbounds accessible only from the local machine, defaults to direct connections, and includes a blocking outbound. It demonstrates the structure and helps validate the local path; it does not include a remote proxy server or change the system proxy automatically. Save it as plain UTF-8 text and run it using a compatible core's custom-configuration option. If the client is already using these ports, stop the existing instance or change the ports in both this example and the test app.
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
JSON objects use braces, arrays use square brackets, and keys and strings must be enclosed in double quotes. Numeric ports are unquoted; Boolean values are lowercase true or false. The examples on this page omit comments and trailing commas so they work with strict JSON parsers. Even if one loading method accepts comments, that does not mean every client import option supports the same syntax.
An empty object is not always equivalent to a missing object. Some protocols allow an empty settings object, while others require a server or user list. Field names are case-sensitive too: outboundTag is a defined key, not an arbitrary label. By contrast, direct and socks-in are tags defined for this example and can be renamed, but update every reference and avoid duplicate tags.
There is no need to fill in every optional object. A complete configuration is not one with the most fields; every field you add should serve a clear purpose. Before you start, note the inbound protocol, port, default outbound and expected routing behavior. Check each section against these four points to avoid copying a complete configuration from elsewhere without knowing which rules are active.
Inbounds: where apps connect
inbounds is an array of entry points. Each inbound needs a listening address, port and protocol, along with protocol-specific settings. The core can handle an app's traffic only if the app actually connects to that inbound. A client showing as running does not mean your browser, terminal and other apps are connected. When troubleshooting, first ask where the app is sending its connection; this is usually more useful than changing routing rules right away.
Check listen, port and protocol together
When listen is 127.0.0.1, the inbound accepts connections only from the local loopback interface. 0.0.0.0 listens on all IPv4 interfaces, exposing it much more broadly. The port is the local port used by this inbound, not the remote server's port. This page uses separate SOCKS 10808 and HTTP 10809 listeners; clients may use a mixed inbound or different ports. Check the active configuration rather than assuming the protocol from a familiar port number.
Point HTTP proxy settings to an HTTP inbound and SOCKS settings to a SOCKS inbound. A browser's HTTP proxy usually cannot establish a proper session through a SOCKS-only port. HTTPS sites can also be reached through an HTTP proxy using a CONNECT tunnel; that does not mean you should change the local proxy address to HTTPS. An app's “secure proxy” label may describe the destination traffic, not TLS on the local inbound.
| Field | Purpose | What to check |
|---|---|---|
tag | Internal name for the inbound | Matches the routing rule's inboundTag |
listen | Local address to bind to | Whether access is limited to this device |
port | Listening port | Whether the port is in use and entered correctly in the app |
protocol | Inbound protocol | Do not confuse SOCKS with HTTP |
settings | Protocol-specific settings | Options such as authentication and UDP |
UDP and the limits of traffic sniffing
udp: true on a SOCKS inbound allows the corresponding UDP forwarding capability; it is not a global UDP switch. The app must use a compatible SOCKS UDP method, and the remote protocol, server and network path must support it too. A working TCP request does not prove that UDP is working. A traditional HTTP proxy is not a general substitute for UDP apps; check how games and real-time communication apps connect.
sniffing can identify a destination domain from some application-layer handshake data, helping domain-based routing when a connection would otherwise expose only an IP address. It does not decrypt traffic and cannot extract a domain from every encrypted connection. The example below uses sniffed results only for routing; check whether the active core supports routeOnly. If it does not, do not simply remove the field and assume behavior is unchanged; confirm whether rewriting the destination is acceptable.
{
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"],
"routeOnly": true
}
}
Merge this block into an inbound object at the same level as protocol, not inside that protocol's settings. A misplaced object may prevent some loaders from starting, while others may ignore the unknown content. Valid JSON syntax is only the first check: confirm that the core accepts the structure and that the expected domain rules are actually matched.
LAN sharing requires access controls
To let another device use the proxy, the client's “Allow connections from LAN” option often changes the listening scope, and the operating system firewall may also apply. The other device should connect to the proxy host's LAN address, not its own loopback address. Limit which devices can connect and configure authentication where needed. Do not expose the inbound to an unknown network just by listening on all interfaces.
On Android, v2rayNG and v2flyNG often also use the system VPN interface and per-app selection. Whether an app uses that interface is a separate question from whether the JSON contains a SOCKS inbound. Check desktop system proxy settings, app-specific proxy settings and Android per-app rules separately. For permissions and background operation, see Android VpnService and per-app proxying.
Outbounds: protocols and the default route
outbounds is the list of exits that handle connections. An outbound can connect directly to a destination, connect to a remote proxy service, or reject traffic. Its protocol describes the protocol the core uses for that outbound, not the protocol the app used to connect to the inbound. Connections from the same SOCKS inbound can go to different outbounds depending on the routing result; inbounds and outbounds do not need a one-to-one mapping.
Default outbound and tag references
In common object-based configurations, connections that match no routing rule use the first outbound. Array order is therefore part of the actual behavior. The opening configuration puts direct first, so unmatched connections go direct by default. In a real remote-proxy setup, explicitly choose the default outbound if unmatched traffic should use the proxy. A tag named proxy does not automatically become the default; tags have no special meaning by themselves.
tag is the name routing rules use to refer to an outbound. A rule's outboundTag must match a defined tag exactly, including capitalization. Use concise, recognizable names and avoid duplicates. Do not confuse a node name or subscription group with an outbound tag: the client may transform interface labels, and they are not guaranteed to appear unchanged in the runtime configuration. Check the generated configuration when troubleshooting.
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {
"response": {
"type": "none"
}
}
}
]
}
freedom connects directly to the destination through the local network; it does not bypass the core. The connection may still be affected by the core's DNS, outbound settings and system network state. blackhole drops or rejects selected traffic and is commonly used to block it explicitly. After a rejection, an app may fail immediately or keep retrying until it times out, depending on its retry behavior. A page that keeps loading does not automatically mean the remote connection is broken.
Remote protocol settings are not interchangeable
Proxy protocols use different server and authentication structures. VMess and VLESS user details are not the same as Trojan's password field, and Shadowsocks requires both sides to use the same encryption method. A share link usually includes the remote address, port, authentication and transport details; check them together after importing. Changing just the server address while keeping another connection's transport or authentication settings can produce valid syntax but a connection that does not work.
The remote server address answers “which service do I connect to?” The request destination answers “where do I ultimately want to go?” They belong to different layers. Keep local listener ports, remote service ports and destination website ports separate too. Successfully connecting to the local port proves only the first link; an unreachable remote port, mismatched authentication or failed TLS can still prevent the final connection. When you see an address in a log, first identify which link it belongs to.
| Object or field | What it controls | What it does not confirm |
|---|---|---|
protocol | Outbound proxy protocol | Whether the transport and certificate are correct |
settings | Protocol parameters such as server and user | Whether local apps are using the proxy |
streamSettings | Transport and connection security | Whether routing selected this outbound |
tag | Identifier referenced by rules | Default outbound or operational status |
Test one outbound before adding routing logic
Before adding multiple outbounds, test one with the same request. Keep a direct-connection control to distinguish an unreachable destination from a proxy-path problem. In a fully custom configuration, the client's “select current server” option may not rewrite your outbound list. Check where the configuration comes from after changing an option in the interface; do not assume automatic selection applies to every custom file.
Multiplexing, chaining and load balancing are advanced behavior controls, not first-line fixes for connection failures. They add concurrency, dependencies and diagnostic complexity. First confirm that the inbound, routing and a single remote connection work, then add features as needed. If protocol terminology is unclear, read How four proxy protocols differ before checking the relevant fields.
Transport & security: the streamSettings hierarchy
Proxy protocols and transport methods are separate layers. The protocol handles sessions and authentication; the transport determines how that data moves across the network. Connection security then controls whether and how mechanisms such as TLS are used. A protocol may support several transports, but a combination works only if both the server and the active core support it. After importing a share link, check the protocol, transport and security settings together; matching protocol names alone do not guarantee compatibility.
What network and security mean
streamSettings is usually at the same level as an outbound's settings. network specifies the underlying transport, while security specifies the connection security mechanism used at that layer. Transport-specific objects provide details such as paths, request headers or service names. Field names and supported values vary by core; do not assume a new transport field from one core is a universal setting for another.
The TLS configuration below shows the object structure and certificate-name field. It is not a complete remote outbound; the example uses a reserved documentation domain, so replace it with the name specified by the server. Do not use this snippet to replace all transport settings in a subscription, or assume that enabling TLS alone will complete a handshake with any remote port.
{
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "example.com",
"allowInsecure": false
}
}
}
serverName is used for TLS Server Name Indication and related certificate-name verification; it does not necessarily match the server address used to establish the underlying connection. The connection can target an IP while the certificate must match a domain. Conversely, changing the server address to a domain does not ensure that the application-layer request header, transport path and TLS name are all correct. Check each one against the server requirements instead of using one field for every name.
Check paths, request headers and certificates
With WebSocket, the path is part of the transport agreement and must match the server or reverse-proxy configuration. Slashes, capitalization and query parameters can all affect matching. The Host header and TLS name may be the same or may differ in a specific deployment; do not fill them in by guesswork. A successful TLS handshake confirms only the security layer, not the subsequent WebSocket upgrade or proxy-protocol authentication.
The gRPC service name is also part of the server-side configuration, not a note in the interface. A transport name that looks right can still fail because of the service name, path forwarding or restrictions from an intermediate network device. Identify whether the failure occurs during TCP connection, TLS handshake, transport handshake or protocol authentication. Each layer depends on the one before it; changing several settings at once makes problems harder to reproduce and locate.
| Layer | What to check | Common symptoms |
|---|---|---|
| Network connection | Remote address, port and reachability | Connection refused or timed out |
| TLS | Name, certificate chain and system time | Certificate or handshake error |
| Transport | Path, Host and service name | Upgrade failure or connection closed |
| Proxy protocol | User, password and protocol parameters | Authentication failure or interrupted request |
Compatibility depends on the core that is actually running
Features such as REALITY and XTLS Vision cannot be enabled just by copying a few fields, and support in the client interface does not mean the active core accepts those settings. For these connections, first confirm the server-provided details and active core, then check the full set of parameters. V2Fly and Xray share some background, but their extensions are not fully interchangeable. See Core differences and configuration compatibility.
If switching cores results in an “unknown transport” or “cannot parse security settings” error, return to a configuration confirmed to be compatible rather than deleting fields one by one until it starts. A successful startup means only that the file was accepted; it does not mean both sides use the same connection semantics. Keep the original connection details and a record of local changes so you can restore the setup without guessing and separate compatibility issues from network problems.
Routing: conditions, order and tags
Routing rules decide which outbound handles a connection. In common field-based configurations, rules are checked in array order, and the first match determines the result. If nothing matches, the default outbound is used. Routing cannot replace a working inbound or fix an outbound that cannot connect. Before building split-routing rules, verify the default path and add a few rules with clear purposes. Avoid importing a large set of conditions you cannot explain.
How conditions within a rule work
Different types of conditions in one rule usually all need to match; for example, both the inbound and destination domain must match. An array of values for the same field lists alternatives. Putting domain and IP lists in one rule therefore does not mean “domain or IP.” To cover both types of destination, create separate rules that point to the same outbound tag.
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:example.com"],
"outboundTag": "block"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
}
]
}
}
This example requires existing direct and block outbounds, along with the relevant domain and IP data files. The first rule blocks an exact documentation example domain to demonstrate rule priority; the next three show common direct-connection categories. This is not a complete routing plan for every network. Unmatched traffic still goes to the first outbound. If the default outbound is also direct, the later rules will not send other traffic through a proxy.
Domain syntax and data files
full: matches an exact domain, domain: matches a domain and its subdomains, regexp: uses a regular expression, and geosite: references a domain category. A plain string may match more broadly than expected, so use the appropriate prefix when you need a precise match. Backslashes in regular expressions also need JSON string escaping. If a pattern is hard to troubleshoot, use a few clear domain conditions instead.
geosite:cn and geoip:cn refer to domain and IP categories respectively. They are not live geolocation lookups or matching datasets. Missing data files, unsupported categories or incompatible file formats can affect loading. Match results for some destinations may also change after updating the client or data. For exceptions that need to remain stable, use clear custom domain rules.
domainStrategy is not a DNS server selector
AsIs generally keeps the original destination form and does not resolve a domain to an IP for routing. IPIfNonMatch attempts resolution after no domain rule matches, then checks the IP. IPOnDemand triggers resolution when routing needs an IP. The exact behavior depends on the core. These options determine when routing needs an IP; the DNS object determines how DNS queries are handled. They are not the same setting.
If an app submits an IP directly, domain rules may have no domain information to match. If the destination remains a domain, whether an IP rule applies depends on the resolution strategy. Traffic sniffing can provide extra information in some cases, but not every connection has a domain. When a rule appears not to work, first check whether the core received a domain or an IP, then review rule order and data categories. Do not send all traffic through the same outbound as a first step.
To verify routing, test a specific domain, an expected direct destination and a destination that should use the default path, each with a new connection. Browsers may reuse pooled connections, so start a fresh connection after changing the configuration and then check the logs. A system proxy bypass list can also send requests directly before they reach the core; that is separate from core routing. For common connection issues, browse the FAQ by troubleshooting topic.
DNS configuration: where resolution happens
The first DNS question is where resolution takes place. The browser, operating system, an app's own resolver, the core's built-in resolver and a remote service may all be involved. Adding a dns object configures the core's built-in resolver; it does not mean the core automatically handles every DNS request on the system. If an app resolves a domain to an IP before passing it to the proxy, the core may never see the original domain.
servers, hosts and query strategy
servers defines the DNS resolvers. Entries can be simple addresses or objects with matching conditions. The example below shows a common split-DNS structure and assumes a core that supports these fields. The IP addresses are public-resolver examples, not a recommendation or a guarantee that they are reachable on every network. Before using them, confirm that they are available over the intended network path.
{
"dns": {
"hosts": {
"example.com": "192.0.2.10"
},
"servers": [
{
"address": "223.5.5.5",
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
"1.1.1.1"
],
"queryStrategy": "UseIPv4"
}
}
hosts defines static mappings for the core's resolver; it does not edit the system hosts file. The example's 192.0.2.10 is a reserved documentation address and cannot be used to reach a real service. Static mappings suit specific, stable needs. Pinning a frequently changing website to one IP for a long time may bypass normal traffic distribution and cause unexpected certificate, reachability or service-region issues.
A server entry with domains provides match conditions for specific domains. expectIPs checks whether the result fits an expected category, but it is not a firewall that restricts access to a particular region. Resolver selection, fallback and result acceptance also depend on the core and other options. Do not assume the server array always tries the second entry only after the first fails, or infer the destination of every query from array order alone.
Validate DNS resolution and connection paths separately
Whether a DNS query can reach a resolver and whether the final website connection uses a proxy are separate questions. Some resolution methods can participate in core routing; modes with local semantics may use the local network path directly. Check the actual implementation. Adding a domain rule that points to a proxy does not necessarily change the outbound used by every DNS query, and changing the DNS address will not fix incorrect remote authentication or transport settings.
Resolvers that use HTTPS also raise a bootstrap question: how is the resolver's own domain resolved first? If the resolver address is a domain and its resolution depends on that same path, you may create a dependency loop. Work out how the resolver and proxy server are found during startup, keep a reachable bootstrap path, and avoid making the proxy server's domain depend on the proxy connection that has not yet been established.
| Setting | Main effect | What to check separately |
|---|---|---|
| System DNS | Apps that use the system resolver | Whether the app has its own resolver |
| Core dns object | Relevant queries initiated by the core | Whether the built-in resolver is actually used |
| Routing domainStrategy | Whether routing attempts resolution | How the outbound connects to the destination |
| Outbound resolution strategy | Preparing the destination address for a connection | Whether the active protocol supports the field |
IPv4, IPv6 and caching
UseIPv4 restricts the relevant query strategy; it does not disable IPv6 on the entire device. An app using its own resolver may still get an IPv6 address and try to connect. Conversely, getting an AAAA record does not mean the network has a working IPv6 route. Check resolution results and connection results separately instead of disabling an entire address family to work around a specific failure.
After changing DNS settings, app and system caches and existing connections may still affect what you observe. Start a new request and compare the destination form and routing choice in the logs. System lookup tools in the command line usually test the system resolver, not necessarily the core's built-in resolver. To test core DNS, send a request through the actual inbound and check the runtime logs; a single system lookup is not proof that the configuration is working.
Policy: connection timeouts and statistics
policy mainly controls connection behavior by user level and system-wide statistics options. “Policy” here does not mean domain-routing rules or system proxy mode. Routing decides which outbound handles a connection; policy controls how long related connections wait, when they close and whether some statistics are recorded. Keeping these objects separate helps avoid changing timeouts to solve an unrelated issue such as routing to the wrong outbound.
How levels relate to user levels
The keys in levels are strings containing level numbers, such as "0". Protocol objects that support user levels can refer to a level in their user configuration. If no level is specified, the default level usually applies, depending on the protocol and core. Levels are not priority rankings and do not make a user's connection faster. Before changing one, confirm that the user object you want to manage actually uses it.
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
}
These example values explain the fields; they are not recommended settings for every situation. handshake controls the time allowed for the relevant handshake stage, connIdle sets the idle-connection timeout, and uplinkOnly and downlinkOnly control how long one side waits after the other side closes. Common implementations use seconds, but these limits apply to the core's connection flow, not the page-load timer shown by a browser.
Timeouts that are too short can interrupt handshakes on high-latency networks or affect long polling, push notifications and connections that briefly have no data. Longer timeouts can retain more idle resources. If connections drop intermittently, first determine whether the cause is a timeout, a remote close or the app ending the session. Do not increase every value at once just because a connection dropped. Over-adjusting can hide link-quality problems and make them harder to reproduce.
Statistics switches are not a complete monitoring interface
User traffic, inbound traffic and outbound traffic statistics measure different things. Turning on a switch does not guarantee that the client will display the corresponding figures; the statistics module, query interface and the client's own sampling method may also need to work together. User statistics may require identifiable user information. Do not equate these counters with network-interface traffic: protocol overhead, retransmissions and traffic from other processes can make the totals differ.
A full custom configuration that needs statistics may also require statistics objects and query capabilities, as specified by the core. An API inbound is part of the management plane and should be limited to the local machine or a trusted network. Do not expose it on an untrusted interface just to read traffic. This page does not provide an example that opens a management port to the network. In a GUI client, use its existing statistics features where possible to avoid conflicting management endpoints.
Adjust policy, logging and concurrency separately
Log verbosity is controlled by the log object, not the statistics switches in policy. Policy statistics count bytes; logs record runtime events. Neither replaces the other. Multiplexing has its own configuration location and is not enabled by turning on user statistics. When investigating resource use, examine connection counts, workload concurrency, log output and statistics needs separately, then adjust the relevant setting.
Operating system restrictions on background connections can affect both desktop and mobile devices. On Android, battery optimization may pause the client, and a network change may break existing connections; increasing connIdle alone cannot fix these issues. First confirm that the process is still running and the system network interface is available, then check core policy settings. Otherwise, a system-level interruption may be mistaken for an idle timeout in the configuration.
To judge whether a change helped, retest on the same network, with the same app and under similar conditions. A short request working does not prove that a long-lived connection works; keeping a connection open does not prove resource use is reasonable. Recording the failure stage and logs is more useful than repeatedly applying supposedly universal optimization settings. Avoid changing options without a clear need; simpler configurations are easier to maintain and more likely to remain compatible with future updates.
Validation & troubleshooting: from file to request
Configuration checks have four layers: whether the text parses, whether the core loads it, whether the app connects, and whether the final path behaves as expected. Passing one layer does not prove the next. Valid JSON can refer to an undefined outbound; a running core may receive no app traffic; and a successful visit may be a direct connection that bypassed the proxy. Look for observable evidence at each layer to determine what your change actually affected.
Start with syntax and load errors
Check quotation marks, commas, matching brackets and field types first. When copying code, do not include explanatory text or code fences in the file. Once the JSON parses, check the core startup log for an unknown protocol, missing data file, invalid tag or port conflict. The reported line and column usually mark where parsing stopped; the missing comma may be on the previous line, so check the boundaries of the surrounding objects too.
Make sure the process is using the file you just edited, not a different configuration regenerated by the client. GUI clients usually provide logs or runtime information, though the menu names may vary. You do not need to switch clients as a first step. Keep a copy of the original file, stop conflicting instances, restart once and record the first error. Later repeated errors may simply be retries triggered by the same underlying cause.
Test through a specific inbound
The two commands below use the separate SOCKS and HTTP inbounds from the opening example. The socks5h proxy scheme passes domain resolution to the proxy side, which helps distinguish it from local DNS resolution. On Windows, specify curl.exe; on other systems, use an available curl command. The test targets a documentation example site. It is not a speed test and does not prove that every app is using the proxy.
curl --noproxy "" --proxy socks5h://127.0.0.1:10808 --head https://example.com/
curl --noproxy "" --proxy http://127.0.0.1:10809 --head https://example.com/
Setting an empty bypass list explicitly helps prevent existing proxy environment variables from affecting the test. If the local port immediately refuses the connection, check the process, listening address and port first. If the local connection succeeds but the remote request times out, check the outbound and network. When comparing against the direct-connection baseline, success proves only that the basic app-to-core-to-destination path works; it does not prove that a usable remote proxy server is configured.
Use log stages to pinpoint the fields to check
warning is suitable for routine use. If you need more detail to locate a problem, temporarily increase log verbosity. Then make an easily identifiable request, note the time, destination, inbound and selected outbound, and restore the usual log level afterward. Detailed logs may contain domains, addresses and connection information. Remove subscription URLs, authentication details and other sensitive data before sharing logs; do not send the entire runtime configuration.
| Symptom | Check first | Next step |
|---|---|---|
| Will not start | Syntax, core compatibility and port conflicts | Return to a working baseline configuration |
| Local connection refused | Process, address and listening port | Check the proxy protocol configured in the app |
| Remote handshake failed | Name, time, transport and authentication | Check each layer against the server requirements |
| Some destinations use the wrong outbound | Rule order, destination form and default outbound | Narrow it down with specific conditions |
| Works in the browser, fails in the terminal | Each app's proxy settings and bypass list | Retest with an explicitly specified inbound |
A “timeout” is an outcome, not a single cause. An unreachable destination, failed DNS lookup, wrong outbound or stalled remote handshake can all look similar. First identify where the failure occurs, then check the relevant fields. For common log messages, see Runtime logs and common errors. If only the terminal is affected, see Troubleshooting system proxy and terminal traffic instead of changing the entire routing setup.
Keep a recoverable change log
For each change, record three things: which object you changed, what you expect to change, and which request you used to test it. After updating a subscription or switching servers, check whether the client kept your custom settings. To roll back, restore the most recent working configuration instead of stacking more patches. If the cause is still unclear, follow the main tutorial to recheck import, mode and connection, then add custom settings back one object at a time using this page.