v2rayN Core Startup Errors: Fix JSON Syntax and Port Conflicts

Does the core exit as soon as you click Start? Follow four steps: review startup output, find the faulty field, check for port conflicts, and verify the core files. Troubleshoot JSON syntax, misspelled fields, and ports in use.

At a glance

This guide covers cases where the v2rayN window stays open but the Xray child process fails to start. Save the full startup output first, then test the actual config with the core in use, and finally check listening ports and program files. Examples use Windows PowerShell and port 10808 for illustration. Replace it with the port in your current config rather than copying the example value.

1. Review startup output: distinguish a core exit from a connection failure

v2rayN is the management interface; Xray is the core that handles connections. An open window doesn’t mean the core is listening on a local port. Conversely, a web page timing out doesn’t prove the core failed to start: the remote host may be unreachable, routing rules may not work as expected, or an app may not use the system proxy. Any of these can happen while the core is running normally.

Startup output Config test Port ownership Core files Request check

Find the latest startup record in the information or log area of the v2rayN main window. The entry name may vary by version, so use the log access point in your current interface. Note the startup time, core name, executable path, config path, and the first error before the process exits. Don’t save only the final “startup failed” message; it usually describes the outcome, not the cause.

Symptom or outputCheck firstNot the first thing to check
failed to load config files appearsConfig path, JSON syntax, field valuesRemote speed test results
failed to listen TCP appearsListen address, port in use, system restrictionsSubscription update frequency
Process stays running, but requests return i/o timeoutRemote reachability, DNS, routing, and transport settingsTreating every problem as a startup failure
System says the program can’t runArchitecture, file path, access permissionsChanging node credentials first

2. Test the actual config: check JSON first, then Xray fields

The settings saved in the v2rayN interface aren’t the same as the runtime config passed to the core. Use startup output to find the actual config path, then make a copy for troubleshooting. Direct edits to an automatically generated runtime file may be overwritten when you switch nodes or restart. Once you find the cause, fix it in the custom config, routing rules, or relevant settings that generated the file.

  1. Stop the failed startup attempt, save the error output, and back up the relevant current config.
  2. Find the file specified in the startup arguments. Don’t guess from its filename or mistake subscription text for the core’s JSON config.
  3. Test the copy with the same Xray executable that v2rayN actually runs.
  4. Change one thing at a time and test again. Fix the next error only after the previous one is gone.

The steps below assume you’re in a test directory containing xray.exe and the copy to test, config.json. This filename is for the example only; v2rayN doesn’t always use this path. The first command checks the executable version. The second tests the config without starting the full proxy service.

.\xray.exe version
.\xray.exe run -test -config ".\config.json"
$LASTEXITCODE

A successful config test means only that the core passed this stage of config checks; it doesn’t guarantee that a port can be bound or a remote host reached. If your core doesn’t recognize the command-line arguments, check that executable’s help output to confirm the correct syntax. Don’t keep trying with an executable from an unknown source.

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

Cause: A syntax issue, such as a trailing comma after the last item in an object, left the parser expecting a key when it encountered a closing brace.

Fix: Check the item immediately before the reported position, remove any trailing comma, and make sure keys use straight double quotes.

Error: unexpected EOF

Cause: The config ended while the parser was expecting more content. Common causes include an incomplete copy, a missing closing bracket or brace, or an unclosed string.

Fix: Check that braces, brackets, and double quotes are paired in your editor. Restore a complete backup if possible; don’t blindly add closing brackets to the end.

Error: json: cannot unmarshal string into Go value of type uint16

Cause: A field that expects a number received a string. The full error may also include a structure or field path.

Fix: Use the full error to locate the field and correct its type as required by the current core. Don’t add or remove quotes from every number indiscriminately.

A config can be structurally valid but still have semantic errors. Xray field names are case-sensitive: outboundTag is not outboundtag. Routing rules must also reference an outbound tag that’s actually defined. Some unknown fields may be ignored rather than causing startup to fail, so “no syntax errors” doesn’t prove that field names are correct.

{
  "type": "field",
  "domain": ["full:example.com"],
  "outboundTag": "proxy"
}

3. Check for local port conflicts: identify the process behind a listening port

If the config test passes but startup still exits while binding a listener, check the port. Find listen, port, and the protocol in the runtime config’s inbounds. A TUN interface is not the same as a regular local proxy listener. The example below assumes TCP port 10808 is in conflict; it isn’t a default for every installation.

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

# Replace 1234 below with the OwningProcess from the previous output
Get-Process -Id 1234 |
  Select-Object Id, ProcessName, Path

If the process path is blank, check the PID in Task Manager. If needed, use a terminal with appropriate permissions. Don’t terminate a process until you’ve confirmed what it is. The port may be in use by another v2rayN instance, a leftover Xray process, or an entirely different local service.

ResultWhat it meansWhat to do
Another proxy instance is listening on 10808Two instances are trying to use the same address and portExit the unused instance normally, then start the current one
Duplicate inbounds in the same configTwo listeners are using conflicting endpointsRemove the duplicate or assign different ports
No listener is shown, but an access-permission error persistsA reserved port range or security policy may be blocking the bindCheck system restrictions; don’t repeatedly force-terminate processes
Listen address is 0.0.0.0 or ::A wildcard address may conflict with another listenerCheck specific addresses as well as IPv4 and IPv6 listener records

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

Cause: Windows rejected a duplicate or conflicting socket bind. The error chain often includes the listen address and port.

Fix: Use the port in the error to find the PID, then exit the conflicting instance. For duplicate inbounds, fix the config source and regenerate the config.

Error: An attempt was made to access a socket in a way forbidden by its access permissions.

Cause: The system rejected the bind request. This may involve a reserved port, exclusive binding, or a security policy, rather than an ordinary process using the port.

Fix: Check reserved port ranges and security logs first, then choose a port that’s permitted. Don’t treat running with elevated privileges as a general fix.

netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp

If you need to change ports, look for the local listening port setting in v2rayN under “Settings” → “Parameter Settings.” The group name may vary between versions; use the generated config as the source of truth. Before changing the test port from 10808 to 10818, for example, confirm that 10818 is free and not restricted. After restarting the core, update any manually configured browser proxy, terminal proxy variables, and other clients as well.

Check: verify clients after changing ports

If the new port is listening but an app still connects to the old one, the client’s settings weren’t updated. That’s not a new core startup issue. Confirm the actual listening endpoint, then check the system proxy and terminal variables. This avoids switching back and forth between two different problems.

4. Check core files: paths, architecture, and dependencies

If even the config test won’t run, focus on the program files. First confirm that the full path in the log exists, then check whether the program can print its version directly. The v2rayN interface directory isn’t necessarily the core directory. Running a same-named program from another folder may test a different copy of Xray.

If the log shows failed to open file or The system cannot find the file specified., check the specific filename in the following lines. A missing executable, config file, or rule resource each calls for a different fix. For relative paths, also check the startup working directory and resource lookup location; confirming that “the file exists somewhere” isn’t enough.

5. Retest in order: verify a local request after the config passes

Finish troubleshooting with a repeatable end-to-end check, not just a change in the interface status. Keep the node, routing, and proxy mode unchanged; test only the part you just fixed. The request examples below apply only if port 10808 is confirmed to provide an HTTP proxy or a compatible mixed inbound. If the inbound supports SOCKS only, use the matching proxy protocol.

# HTTP proxy or mixed inbound with HTTP support
curl.exe --proxy http://127.0.0.1:10808 --connect-timeout 10 --max-time 20 https://example.com/

# SOCKS-only inbound: let the proxy resolve the destination hostname
curl.exe --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 --max-time 20 https://example.com/
  1. Config: Confirm that the core test passes with the same runtime config, then save the corrected source settings.
  2. Startup: Confirm that the core stays running and the original error no longer appears in the startup log.
  3. Listener: Check the target port again and confirm that the owning process is the core you just started.
  4. Request: Send one request through the specified proxy endpoint, then compare its destination and outbound entry in the logs.

The 10-second connection timeout and 20-second total limit in the example are test settings, not performance benchmarks. If a local “connection refused” error occurs, recheck the listening endpoint. If the proxy connection succeeds but the remote request times out, continue checking the node, DNS, and routing. One successful request doesn’t prove every route works as intended, but it does distinguish a core startup failure from a problem with a specific connection.

6. Common questions: subscriptions, config tests, and reinstalling

The core stopped starting right after a subscription update. Should I delete the subscription?

Keep the existing group and error records for now. Test another config in the same group and see whether the issue affects only one node. Then check whether any new transport fields match the selected core. Deleting the whole group removes useful comparison data and doesn’t identify the cause.

A JSON validator says the config is fine. Why does Xray still exit?

General-purpose validators mostly check syntax; they don’t understand every core field or runtime dependency. Test the config with the actual Xray executable, then check whether startup fails due to a port conflict or missing resource. Don’t submit configs containing credentials to online validation services.

My config changes disappear after a restart. How do I save them?

You probably changed a temporary generated file. Find the corresponding custom config, routing rule, or source setting under “Settings” → “Parameter Settings.” Make the change there, restart, and confirm the regenerated config includes it.

Will downloading and reinstalling the package fix a port conflict?

Not by itself. First find the PID using the actual port, such as 10808. If the process holding it is still running, a newly installed core may fail to bind too. Reinstall only after confirming that a file is missing, can’t run, or doesn’t match your system architecture. Keep a config backup.

Download v2rayNChoose a platform and package