Oct 3, 2026 · Troubleshooting · About 12 min

v2rayN Core Won’t Start? How to Read Xray Logs and Fix Configuration Errors

Read startup errors line by line by log level. Covers common causes such as port conflicts, JSON syntax errors, missing geo files, and misspelled fields, with steps to fix them.

At a glance

This guide is for Windows users whose v2rayN setup fails to start with the Xray core selected. Start by saving a complete startup log, then check configuration loading, local ports, routing resources, and field compatibility. Finish by testing the configuration and verifying an actual request. The ports shown are examples, not defaults for every installation.

1. Tell a Core Startup Failure from a Request Failure

v2rayN is the management interface; Xray is the core that runs the proxy configuration. An open interface doesn’t mean the core is running, and a website timing out doesn’t mean the core failed to start. For a startup failure, check the local configuration and runtime environment. For a request failure, investigate the node, DNS, and remote route.

Don’t rely on the last status message alone. Open the information or log panel in the main window, clear old entries, then restart the active configuration and save the complete sequence from configuration loading through process exit. Log panel names vary by release, so use the labels in your version.

Load configuration Parse fields Load resources Bind port Handle requests

2. Find the Root Cause in the Log Level and Error Chain

Xray commonly uses the log levels debug, info, warning, error, and none. none disables routine log output, so it’s not useful for troubleshooting. Start with info; if the request path isn’t clear, temporarily switch to debug, then restore the original level to avoid generating excessive connection details.

In v2rayN versions that provide the option, look under Settings → Parameter Settings for log options, save your changes, and restart the active configuration. With custom JSON, check the log section in the file rather than assuming the interface setting overrides it. Configuration parsing errors may also go straight to the process console, so keep the core output from the interface as well.

Level or outputWhat it tells youNext step
debugShows more runtime detail and routing cluesReproduce the issue once, save the log, then restore the original level
infoRecords startup and routine runtime activityConfirm the core version, configuration path, and startup sequence
warningMay indicate a one-off connection or runtime issueUse timestamps and process status to determine whether the core actually exited
errorRecords more serious processing errorsRead the full error chain, not just the level label
Startup error in the consoleConfiguration initialization may not have completedCheck paths, syntax, and resources that failed to load first

Error chains often use > to link multiple contexts. The example below shows a typical structure; module prefixes and wording vary by core version. The outer message says loading failed, while the inner messages explain that the configuration couldn’t be read and point to the specific syntax issue.

Failed to start: main: failed to load config files: [config.json]
> infra/conf/serial: failed to read config file
> invalid character '}' looking for beginning of object key string

Takeaway: Fix the innermost actionable error first

For an error chain like this, check for an extra comma before the closing brace first—not DNS or the selected node. Restart after fixing it, then address the next issue surfaced by the new log.

3. Port Conflicts: Check the Listening Address and Process

A local inbound needs an address and port to bind to. Two processes can’t normally use the same listening endpoint at once. A duplicate core process, another proxy, or even duplicate inbounds in one configuration can cause a conflict. Copy the actual port from the log instead of guessing the default from a guide.

10808
Example local inbound port used in this guide
10809
Example second listening port used in this guide
127.0.0.1
Loopback address accessible only from this machine

Error: Only one usage of each socket address (protocol/network address/port) is normally permitted.

Cause: This common Windows bind error means the port the core tried to use is already occupied.

Fix: Find the process listening on that port and confirm what it’s for. Close a duplicate process normally, or change the local inbound port and update the application’s proxy settings to match.

In PowerShell, the commands below check which process is listening on the example TCP port 10808. Check the process name and path before deciding whether to close it; don’t force-terminate a process based on its ID alone.

Get-NetTCPConnection -State Listen -LocalPort 10808 |
  Select-Object LocalAddress, LocalPort, OwningProcess

Get-NetTCPConnection -State Listen -LocalPort 10808 |
  ForEach-Object { Get-Process -Id $_.OwningProcess } |
  Select-Object Id, ProcessName, Path
  1. If the process is an old Xray instance, exit it normally from its client first. Once it has stopped, start v2rayN again.
  2. If another program needs to keep that port, choose a free one in the local inbound settings. If you use a custom configuration, check all inbounds for duplicate bindings.
  3. After changing the port, check that your browser’s manual proxy settings and the system proxy no longer point to the old port. If the core starts but an app still connects to the old port, you’ll get a different connection error.
  4. If the error says forbidden by its access permissions, don’t assume the port is occupied. Check the system’s reserved ranges with netsh interface ipv4 show excludedportrange protocol=tcp, then investigate security policies.

4. JSON Syntax Errors: Test the File Used at Startup

Saving changes in the node editor doesn’t guarantee that custom snippets form valid configuration. Common problems include a trailing comma, curly quotation marks copied from a document, a missing closing quote, or unescaped backslashes in Windows paths. Use forward slashes in paths, or write each backslash as \\ in a JSON string.

Error: unexpected EOF

Cause: The parser reached the end of the file before the expected content was complete. An object, array, or string may be unclosed, or the exported file may have been truncated.

Fix: Check the end of the file and the most recently edited section, close the structure correctly, and test again. Don’t just append a closing brace without checking what’s missing.

Error: invalid character '}' looking for beginning of object key string

Cause: After a comma in an object, there’s no valid next key. A common cause is a trailing comma after the last field.

Fix: Remove the extra comma, make sure keys use straight double quotes, and test the complete file.

Open PowerShell in the directory containing the Xray executable. Name a copy of the configuration actually used for this run config.json, then run the command below. If the file is elsewhere, use its real full path. Testing an old backup won’t verify the startup configuration v2rayN just generated.

.\xray.exe version
.\xray.exe run -test -config .\config.json

run -test checks whether the current core can load the configuration; it doesn’t replace testing normal port binding or remote connectivity. Use the same resource directory and environment variables as the client, or a manual test may fail to find geo files even though the client can. Auto-generated files may be overwritten at the next startup, so make the lasting change in the node editor, routing settings, or custom configuration source file.

5. Missing Geo Files: Check File Paths and Rule Categories

geoip:private and geosite:cn aren’t plain text that gets expanded automatically. When Xray loads these rules, it needs to read the corresponding data files. Missing files, an incorrect working directory, an overridden resource path, or a nonexistent category can all prevent configuration from loading. Copying only the JSON to another directory often leaves these dependencies behind.

Error: failed to load GeoIP

Cause: The error chain points to a failed GeoIP rule load. The data file may be missing or unreadable, or the category may not match.

Fix: Read the rest of the error chain for the file name, system error, or category. Then check the resource directory, read permissions, and rule content as appropriate.

Error: The system cannot find the file specified.

Cause: If the same error chain points to geosite.dat or geoip.dat, that file couldn’t be found at the path used for this lookup.

Fix: Restore the data file to the resource directory used by the client, and check whether a custom startup environment points to the wrong resource path.

6. Field Names and Nesting: Valid JSON Can Still Be Misconfigured

Valid JSON only means its braces, quotes, and other syntax can be parsed. It doesn’t guarantee that fields are in the right place, have valid values, or match the core’s capabilities. Check which core’s configuration format a copied snippet uses. v2rayN’s interface settings and Xray’s native JSON are different formats; you can’t give the interface settings file directly to Xray to run.

For example, domainStrategy belongs under routing, not inside an individual rule in rules. This is only a routing snippet. It assumes the full configuration defines a direct outbound named direct and that the required geo data is available; it isn’t a complete, runnable configuration.

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

Takeaway: Test “Loads Successfully” and “Works as Intended” Separately

First use a configuration test to rule out structural errors. Then start the core normally and verify that it listens on the expected port. Finally, send a request and check the selected outbound. Testing one layer at a time keeps an ineffective field from being mistaken for a node failure.

7. Verify the Fix and Answers to Common Questions

Change one clearly identified issue at a time, then restart and save the new log. Don’t upgrade the core, change ports, edit routing, and switch nodes all at once; even if the connection comes back, you won’t know which change fixed it. Once everything works, restore the original log level and save a working configuration copy.

  1. Configuration check: The current core tests the actual configuration without errors reading it, parsing fields, or loading resources.
  2. Process check: After a normal startup, the process stays running and the expected local port is listening instead of the core exiting immediately.
  3. Request check: Configure an app to use the new port to reach a destination. Check the logs to confirm the request reaches the core, then look for any new remote connection errors.
  4. Persistence check: Close and reopen v2rayN to make sure the fix wasn’t overwritten by an auto-generated configuration.

v2rayN still won’t start after reinstalling. Should I reinstall it again?

First check whether the same broken configuration is still in use or an old process is still occupying the port. Keep a copy of the original, reproduce the issue once with as few custom settings as possible, and follow the new log. Reinstalling repeatedly won’t resolve a system port conflict.

Running as administrator fixed it. Is it safe to keep doing that?

A standard loopback proxy listener usually doesn’t need administrator privileges. Check the directory permissions and security software against the log first. If you enabled a TUN feature that needs elevated permissions, disable it temporarily to test a standard local inbound, then troubleshoot the permissions separately.

The configuration test passes, but my browser says the connection was refused. What should I do?

Start the core normally, check the actual listening port, and verify the browser and system proxy settings. The test command doesn’t keep the proxy service running; if you only tested the configuration and didn’t start the core, connections to the local port will still be refused.

Does a timeout in the log mean the core didn’t start?

No. Check whether the timeout happened during startup or after an app sent a request. If the core is still listening and the log shows request handling, investigate server address resolution, the remote port, and transport settings instead of repeatedly changing local JSON syntax.

Download the clientv2rayN / v2rayNG