Use this guide when v2rayN opens, but the core exits immediately or repeatedly reports a configuration load failure. First confirm which core actually launched and which config file it loaded. Then follow the error chain to distinguish a listener failure from a JSON parsing error, an unsupported configuration field, or a routing data issue. Fix one problem at a time and retest with the same config to avoid confusing startup failures with connection problems.
First, tell a core startup failure from a connection problem
v2rayN is the client interface; cores such as Xray and V2Ray load the configuration, open local listeners, and handle connections. Seeing servers in the main window doesn’t mean the core is running. Nor does an enabled system proxy prove that anything is listening on its local port. Start with the log from the latest launch—not the browser’s “This site can’t be reached” message.
If the log shows the core exiting right after loading the config, with messages such as Failed to start, failed to load config, or a bind failure, check the local configuration first. If the core stays running and a local proxy port is listening, but requests time out, fail with a certificate error, or are refused, investigate the server address, TLS, and network path instead. Log wording varies by core version; the snippets below are common examples, not exact strings to match.
- Config loading: Look for
config,json,line, andoffset. The proxy listener usually hasn’t been created yet. - Listener setup: Look for
listen,bind, the local address, and the port. Check for port conflicts and listener address issues first. - Request handling: Look for the destination domain, remote port,
timeout, andx509. Don’t start by changing JSON punctuation.
Keep the current log and config path
Note the v2rayN client version shown under Help → About, then record the core name, version, and config file path from the startup log. Some menu locations differ between the desktop and WPF editions. This guide refers to Settings → Parameter Settings; exact section names depend on your version. The client version alone doesn’t tell you which core is running, and finding a file with the right name in the installation folder doesn’t prove that it was loaded.
-
Save the old log
Copy the current error into a local text file, then clear the log display in the main window. Select the current server and set it as active to trigger one core restart. Keep the complete, continuous log from that attempt.
-
Confirm the core
Check the startup line for the executable name and version. If you recently changed the selected core, review the core-related options under Settings → Parameter Settings. Trust the actual startup output.
-
Find the config file
Record the full path of the loaded config. Configs generated for standard nodes are handled differently from custom configs. Copy the failing file for diagnosis; don’t overwrite the client’s persistent settings.
-
Read to the end
Follow the same error chain from the initial message to the final cause. For example, if “config load failed” is followed by “file not found,” the missing file is what you need to fix. Don’t stop at the first failure message.
A runtime config for a standard node may be regenerated when you set a server as active, change routing, or restart. Directly editing the generated config.json often leads to the fix disappearing on the next launch. Once you’ve found the cause, fix it in the node editor, routing settings, or parameter settings. Maintain the file directly only when you’re deliberately using a custom config.
Port conflicts: identify the listener before changing ports
A common cause is another client instance or a leftover core process occupying the local listening port. The Windows example below uses 127.0.0.1:10808 for troubleshooting only; your version may use a different port. Check the local listener settings under Settings → Parameter Settings. If SOCKS, HTTP, or mixed ports are listed separately, check each one—don’t assume the example value applies.
Error: bind: address already in use
Cause and fix: The target address and port are already in use. Windows may also report Only one usage of each socket address. Identify the process listening on the port, close duplicate instances normally, or change the local listening port and restart the core.
Run the following command in PowerShell to show only TCP listeners. This avoids mistaking a remote connection that happens to use the same port number for a local conflict. OwningProcess is the process ID. Check the process name and executable path before deciding whether to close it.
Get-NetTCPConnection -State Listen -LocalPort 10808 |
Select-Object LocalAddress, LocalPort, OwningProcess
Get-NetTCPConnection -State Listen -LocalPort 10808 |
ForEach-Object { Get-Process -Id $_.OwningProcess }
No results means no TCP listener was found on that port at the time of the query; it doesn’t prove the config is correct. Also check the address shown in the log, possible UDP conflicts, and system restrictions such as access permissions. If you change the port to 10809, update any browser or terminal where you entered the proxy manually. If the client manages the system proxy, reset it to apply the new port. Make sure the alternate port is free before testing.
JSON syntax errors: fix the structure before checking settings
JSON parsing failures often follow edits to a custom config or routing rule, or pasted snippets. Common causes include a missing comma between object members, curly quotation marks around strings, an unclosed bracket, or a trailing comma after the last item. Support for extensions such as comments varies between loaders, so use strict JSON in a diagnostic copy when troubleshooting across core versions.
Error: invalid character '}' looking for beginning of object key string
Cause and fix: The structure before the closing brace doesn’t meet the parser’s requirements. A common cause is a trailing comma after the last item. Check the reported position and the line above it, remove the extra separator, and match up the brackets.
Error: unexpected EOF
Cause and fix: The file ended before the content was complete, possibly because a closing bracket is missing or the file wasn’t saved in full. Check the end of the file, restore the complete config, and run a syntax check.
This is a valid JSON object fragment demonstrating numeric ports, quoted strings, and a closed array. It is not a complete, runnable config. When adding a rule fragment to an existing file, confirm which parent field it belongs under; don’t concatenate two complete JSON objects.
{
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
}
}
]
}
- If the log gives a line and column, check that position first, then inspect the preceding line. The parser may point to where it could no longer continue, not where the error began.
- If the log gives only a byte offset, don’t treat it as a character count—especially with non-ASCII text. Use your local editor’s JSON tools to find the position instead of counting by hand.
- Don’t paste a full config containing server addresses, user identifiers, or subscription details into an online formatter. When sharing an error, keep the structure and field names but redact credentials.
Unknown fields and unsupported config values
A successful JSON parse proves only that the file is structurally valid; it doesn’t mean the core supports every protocol, transport, or setting in it. v2rayN’s interface settings, V2Ray config, and Xray config are different file types. Treating a client settings file as a core config, or importing a config for a different core, can cause startup failures or unexpected behavior.
Keep in mind that unknown fields don’t always trigger an error; some code paths ignore unrecognized keys. The absence of an “unknown field” message doesn’t prove a key is spelled correctly. More commonly, a config value isn’t supported—for example, unknown transport protocol. Check the transport setting and the core actually in use instead of changing JSON punctuation.
Error: unknown field
Cause and fix: A strict decoding path rejected an unrecognized field. Note the field name that follows, then check its nesting level, spelling, and support in the current core’s documentation. If the error comes from client import, first confirm whether you’re importing a node, a custom core config, or client settings.
Error: unknown transport protocol
Cause and fix: The current core doesn’t recognize the transport identifier in the config. Check the transport setting in the node editor and the core version. Don’t switch to a different transport at random just to clear the error.
- Check nesting first:
streamSettingsbelongs inside the relevant inbound or outbound config object; don’t move it to the config root. - Then check data types: The boolean
trueis not the same as the string"true". Use the object, array, and number types required by the relevant core. - Finally, check compatibility: New fields may require a newer core. When updating, keep the client and its required core components intact; don’t replace a single executable with an unverified copy.
VMess and VLESS are protocol names, not interchangeable troubleshooting switches. The server protocol, transport, and security settings must match. For a standard node imported from a subscription, reimport a valid config and check the server requirements first. For a custom config, keep the original file and compare suspicious fields against what the current core supports.
Missing geo files: check the file, path, and category name
Rules using geoip:cn or geosite:cn in configs based on the legacy DAT format usually require the corresponding geoip.dat and geosite.dat files. An error chain may first say “failed to build routing rules” and only mention the unreadable data file or missing category at the end. The first message is the consequence; the last one tells you whether to restore a file or change a rule.
Error: failed to load GeoIP
Cause and fix: GeoIP data couldn’t be loaded. Check the path and the system error that follows. If it says no such file or directory, check the actual resource directory and restore the required geoip.dat.
Error: failed to load geosite
Cause and fix: Domain category data couldn’t be read, or the requested category isn’t in the file. Determine whether the file is missing, unreadable, or lacks the category, then fix the resource path, access permissions, or category name in the rule as appropriate.
- Copy the full resource path from the log. Don’t assume the working directory is the program directory; custom launch options and resource path settings can change where files are found.
- If the file is missing, check the client’s resource update option and update log. If needed, restore the bundled components from the complete client package, then confirm that the files were written to the expected directory.
- If the file exists but the category doesn’t, check the category name in the rule and where the data came from. Not all data files contain the same categories, and renaming a file won’t add missing data.
- If the core starts after you temporarily disable custom rules that use the category, you’ve narrowed the problem to the rule and its data dependency. Restore the data and verify routing again before relying on the setup.
Retest in the same order after each fix
Change one variable at a time, then restart the core and save the new log. If you change the node, port, and core and remove routing rules all at once, you won’t know what fixed the problem. For a custom Xray config, test it with the matching Xray executable. Run the command below from the directory containing the diagnostic copy, named config.json.
.\xray.exe run -test -config .\config.json
This command is for Xray versions that support this command-line syntax. Check the help output for other cores rather than copying it. Use the same resource environment as the client during testing; otherwise, a different geo file search path may produce unrelated errors. A successful config test doesn’t prove the remote connection works or that the port can be bound at runtime. Verify it in the client too.
- Check 1: The config loads. The log no longer reports parsing errors, config build failures, or data file load failures.
- Check 2: The listener is up. Use a port query to confirm the expected address, port, and process, and make sure the core doesn’t exit immediately.
- Check 3: Requests get through. Configure the app to use the correct local proxy, then check the connection log. Investigate any TLS or timeout errors that appear separately.
- Check 4: The settings persist. Set the server as active again and restart the client. Confirm the fix is saved to the config source, not just a temporary file.
v2rayN core startup: FAQs
Why does the error come back after I edit config.json?
First check whether it’s a runtime config generated by the client. For a standard node, change the source in the node editor, routing settings, or Settings → Parameter Settings, then set the server as active again to regenerate the config. For a custom config, verify the actual loaded path so you don’t end up editing a backup.
Can updating the subscription fix a core startup failure?
Only if the problem is caused by a subscription node setting. Repeated subscription updates won’t fix a port conflict, a damaged JSON file, or missing local geo files. Follow the error chain to its final cause first.
The port looks free. Why does bind still fail?
Check whether the listening address in the log belongs to this machine and whether the system restricts the port. If the error includes cannot assign requested address, check the address first. If it mentions permission denied, check system restrictions. Not every bind error means another process has taken the port.
What should I include when asking for help with a log?
Include the client and core versions, operating system, continuous log from launch to exit, and any recent changes. Redact subscription links, user identifiers, and authentication details. Keep the error field names, local port, and path structure so others can diagnose the issue without seeing your credentials.