V2Ray Core Won’t Start? Fix v2rayN JSON Config Errors

Can’t connect after clicking Start? Learn to read core logs and fix common startup issues, including port conflicts, typos, routing rules, and missing geo data.

At a Glance

First, confirm whether the core actually exited. Then find the first specific error in the current startup log. This guide covers v2rayN configuration and startup issues, with checks for JSON parsing, field semantics, routing and resource loading, and port binding—in that order. You’ll learn how to preserve useful evidence, make one change at a time, and tell startup failures apart from connection problems after startup.

First, identify the problem: core startup or connectivity

A webpage failing to load doesn’t necessarily mean the V2Ray core failed to start. v2rayN manages servers, subscriptions, and proxy settings; the selected core handles connections. That core may be Xray or V2Fly. An open main window only shows that the client is running—it doesn’t confirm that the core started successfully.

Startup failures usually occur while reading the configuration, building inbounds and outbounds, loading routing resources, or binding a local port. If the core is already listening on a local port and you then see server connection timeouts or TLS handshake failures, investigate the network and server settings instead. Repeatedly updating your subscription won’t fix a local JSON syntax error.

Read configuration Build routing rules Load resources Listen on port Handle connections
Log or symptomWhat to check firstNext step
Process exits immediately after a configuration parsing errorConfiguration failed to loadCheck the file and field named in the error
Failed to bind local port 10808Listener failed to startFind the process using that port
Startup message appears, and the configured port is listeningThe core has probably startedCheck the system proxy, routing, and outbound connection
Timeout occurs only when you try to open a webpageConnection failure after startupCheck the server address, port, and transport settings

The 10808 value in this table is only an example. Use the local listener settings under Settings → Parameters and the generated configuration to find the actual port. If that port is open, another client instance may be listening on it, so check which process owns it.

Save the complete log from one startup attempt

Capture the evidence before changing the configuration. The last log line often just summarizes the startup failure; the actual cause is usually in the core output above it. Follow the error chain to the most specific parsing, file-reading, or system error. The context from the same startup attempt is more useful than an isolated message.

  1. Record your environment

    Note the v2rayN version, operating system, selected core, and version reported in the core startup output. Record the client and core versions separately; one is not a substitute for the other.

  2. Check your settings

    Open Settings → Parameters and note the local listening port. If your version has a Core Type setting, note the selected option too. Settings may be grouped differently across versions; the executable actually launched in the current log is the definitive source.

  3. Reproduce the issue once

    Open the log or output panel on the main screen, note the current time, then select Set as active server for the server you’re testing. Make sure the log is from this startup attempt; don’t mix it with temporary core output from an earlier speed test.

  4. Save the full error chain

    Save everything from the core version line through the exit message. Keep the configuration path, error field, and original system error. Before sharing, redact subscription tokens, server credentials, and personal folder names.

  5. Change one thing at a time

    Change only one category of settings, then try starting again. If the error changes from a parsing failure to a port conflict, troubleshooting has moved to the next stage. Don’t mistake the two messages for the same cause.

JSON syntax: check commas, quotes, and value types first

A JSON parsing error happens before the configuration fields are used. In strict JSON, object keys and strings must use double quotes, and the last member can’t have a trailing comma. Some core loaders accept extensions such as comments, but don’t assume every tool supports the same syntax.

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

Cause: Often, there’s a trailing comma after the last object member, so the parser expects another key.

Fix: Check the line before the reported position, remove the extra comma before the closing brace, then test the configuration with the same core.

Error: unexpected EOF

Cause: The file ends before the content is complete. A bracket may be unclosed, or the file may have been truncated.

Fix: Check the closing braces, brackets, and double quotes, and make sure the editor saved the entire file.

Error: cannot unmarshal string into Go value of type uint16

Cause: A field that expects an integer received a string. The full log usually identifies the field or structure involved.

Fix: Set the value type expected by the current core. Don’t add quotes to every number or remove quotes from every string.

This snippet demonstrates only a trailing-comma error in strict JSON; it isn’t a complete, runnable proxy configuration. Even if a core accepts multiple port formats for a field, JSON object boundaries must still be valid.

{
  "listen": "127.0.0.1",
  "port": 10808,
}

There’s an extra comma after 10808 above. The corrected version is:

{
  "listen": "127.0.0.1",
  "port": 10808
}

Fields and routing: valid JSON doesn’t guarantee a usable configuration

Valid JSON only means the content can be read; it doesn’t mean the core recognizes the protocol, transport options, or routing rules. Field names are usually case-sensitive. A client configuration, subscription text, and core runtime configuration are different structures—a subscription can’t simply be used as core JSON.

A misspelled field doesn’t always trigger an “unknown field” error. Some loaders ignore unknown keys, leaving required fields missing or options at their defaults. A successful test alone doesn’t prove that every custom field took effect.

What to checkSpecific checksHow to fix it
Protocol and transportWhether protocol and the transport settings are supported by the selected coreCheck which core is selected; don’t reuse another core’s entire configuration unchanged
Outbound tagsWhether the outboundTag value matches an actual outbound tagMatch the original capitalization; after testing, verify where traffic is routed
Routing rulesWhether routing.rules is an array and each rule has valid matching conditionsRemove unintended empty rules; check the value types of fields such as domain and ip
Resource referencesWhether the files and tags referenced by geosite:cn and geoip:private existMake sure resource versions, paths, and referenced tags match

This is a common routing snippet; merge it only into an existing, complete configuration. It requires an outbound tagged direct and a resource file that the core can read and that contains the referenced tags.

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

Bottom line: simplify the rules first, then restore traffic routing

Back up your current routing setup, then temporarily switch to the client’s built-in simplified option. If the same server starts, restore custom rules in batches, one group at a time, to identify the resource reference or rule field that triggers the error.

After startup, check the rule order too. A broad rule placed first may match traffic before more specific rules can take effect. That’s a traffic-routing logic issue, not a JSON parsing failure. For related concepts, see the routing section in Deep Dive.

Port conflicts: find the process before stopping anything

A conflict with a local listener has nothing to do with the remote server’s port. If the core tries to bind to 127.0.0.1:10808 while another process is already using that address and port, startup may fail. Common causes include another v2rayN instance still running or a core left behind by a previous startup.

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

Cause: Windows rejected a duplicate listener. The full error usually includes the address and port that are already in use.

Fix: Identify the listening process, then close the duplicate instance normally, or change the local port and update any apps that use it.

Error: bind: address already in use

Cause: In environments such as Linux, another process is already using the same listening address and port.

Fix: Use your system’s port inspection tools to identify the process. Avoid starting two cores with the same configuration at the same time.

In Windows PowerShell, these commands list the processes listening on TCP port 10808 and their process names; they won’t stop any processes. If your configuration uses a different port, replace 10808 with the value in the log.

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

Get-NetTCPConnection -LocalPort 10808 -State Listen |
  ForEach-Object { Get-Process -Id $_.OwningProcess }

Geo resources: distinguish missing files from missing tags

geosite.dat provides domain classifications, while geoip.dat provides IP classifications. If a rule references these resources, the configuration may fail to build if a file is missing or unreadable, or if it lacks a required tag. Switching servers won’t fix a local resource-loading error.

Error: failed to load geosite

Cause: The domain resource failed to load. The rest of the error chain should indicate whether the problem is file access or a missing category tag.

Fix: Use the full log to confirm the path and tag, then restore the resource or correct the rule reference. Don’t assume the file is corrupted based on this message alone.

Error: no such file or directory

Cause: The file named in the log doesn’t exist. Treat this as a missing geo resource only if the path actually points to a geo file.

Fix: Check the resource directory and the startup location, restore the missing file, and make sure the process has permission to read it.

  1. Check the path. Keep the filename and directory shown in the error. Starting through the client and launching from a terminal may use different working directories or resource lookup settings.
  2. Check the tag. If the error says a list doesn’t exist, check the category name in the rule. A file being present doesn’t mean every tag is available.
  3. Restore the resources. Use the resource update feature in your current v2rayN version or restore the matching files from the complete client package. Don’t use data from an unknown source or in an unknown format.
  4. Test in isolation. Make a backup, temporarily remove the rules that reference the category, and test again. This is only a diagnostic step; it doesn’t complete your final routing setup.

Test with the same core, then verify a normal startup

Use the core and a copy of the configuration actually selected by v2rayN. Xray and V2Fly have different command-line entry points; the examples below show a common Xray command and the V2Fly 5.x subcommand form. Check the program’s help output for the correct options before running a command—don’t use commands intended for a different core.

# PowerShell: run from the relevant core directory; config.json is a test copy
.\xray.exe -test -config .\config.json

# V2Fly 5.x subcommand form
.\v2ray.exe test -c .\config.json

A passing configuration test doesn’t guarantee a successful startup. Test mode mainly checks parsing and configuration building; it doesn’t replace a real listener or prove that the remote server is reachable. A terminal test may also fail to find resources if its working directory differs. Match the test environment to the client’s startup environment.

The test passed, so why does startup still fail?

Check the normal startup log again. If port binding failed, find the process using the actual port. If the resource path failed again, compare the client’s startup directory with the terminal’s. “Configuration parses” doesn’t mean “network works.”

It only fails after switching cores. What should I check first?

Switch back to the original core first to confirm the configuration still works, then check whether the new core supports the protocol and transport. Adapt custom configurations field by field; changing only the executable name isn’t enough. For a standard server, check the client selection against the core shown in the startup log.

Can’t start any servers after updating the subscription?

Check the shared local port, routing setup, and geo resources first. If every server produces the same local error, focus on shared settings. If only one type of server fails, check its protocol and transport settings.

What should I include when asking for help?

Include the client and core versions, the complete error chain from one startup attempt, whether custom routing is enabled, your most recent change, and the tests you’ve run. Redact tokens and server credentials from subscription links; remove personal information from configuration paths too.

Working through these checks in order breaks a startup failure into smaller, verifiable problems. If you’ve passed all three checks but a specific site is still unreachable, investigate DNS, the server, and routing instead of continuing to edit JSON that already passes testing. For more common issues, visit the Help Center.

Download v2rayNChoose a platform and installer