2dust/v2rayN · critical · Exception

Failed to run Core, please check the prompt information

Error message

Failed to run Core, please check the prompt information

What it means

Thrown by the non-sudo core runner after StartAsync plus a 100ms wait when the process is null or already exited. Unlike the admin runner, this path starts the core directly (no sudo) and uses a fixed 100ms liveness probe, which can produce false failures on slow-starting cores.

Source

Thrown at v2rayN/ServiceLib/Manager/CoreManager.cs:358

        }

        var procService = new ProcessService(
            fileName: fileName,
            arguments: string.Format(coreInfo.Arguments, coreInfo.AbsolutePath ? Utils.GetBinConfigPath(configPath).AppendQuotes() : configPath),
            workingDirectory: Utils.GetBinConfigPath(),
            displayLog: displayLog,
            redirectInput: false,
            environmentVars: environmentVars,
            updateFunc: _updateFunc
        );

        await procService.StartAsync();

        await Task.Delay(100);

        if (procService is null or { HasExited: true })
        {
            throw new Exception(ResUI.FailedToRunCore);
        }
        AddProcessJob(procService.Handle);

        return procService;
    }

    private void AddProcessJob(nint processHandle)
    {
        if (Utils.IsWindows())
        {
            _processJob ??= new();
            try
            {
                _processJob?.AddProcess(processHandle);
            }
            catch { }
        }
    }

View on GitHub (pinned to e01717d832)

Solutions

  1. Inspect the displayLog/updateFunc output for the core's startup error (bad config, missing lib, etc.).
  2. Run the same core binary with the same arguments and working directory manually to reproduce.
  3. Validate the generated config file and the coreInfo.Arguments format string.
  4. Confirm the binary is executable and all dependencies resolve (ldd on Linux).
  5. If the core legitimately needs >100ms to start, increase the liveness delay or poll HasExited instead of a single check.

Example fix

// before - fixed 100ms probe, opaque error
await Task.Delay(100);
if (procService is null or { HasExited: true })
    throw new Exception(ResUI.FailedToRunCore);

// after - poll briefly and include exit code/output
using var startCts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
while (!startCts.IsCancellationRequested)
{
    if (procService is null or { HasExited: true })
        throw new Exception($"{ResUI.FailedToRunCore} (exit={procService?.ExitCode}); see core log.");
    if (!procService.HasExited) break;
    await Task.Delay(100, startCts.Token);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight checks before starting the core
if (!File.Exists(fileName)) throw new FileNotFoundException("Core binary not found", fileName);
// validate config path exists
if (!File.Exists(configPath)) throw new FileNotFoundException("Config file not found", configPath);

Type guard

static bool IsCoreExecutablePresent(string fileName) => File.Exists(fileName);

Try / catch

try
{
    var proc = await coreManager.RunCore();
}
catch (Exception ex) when (ex.Message == ResUI.FailedToRunCore)
{
    // core exited within 100ms; almost always a bad config or missing dependency
    _log?.Error("Core failed to start; check config and dependencies (ldd).");
}

Prevention

When it happens

Trigger: CoreManager builds a ProcessService with fileName/arguments/workingDirectory/environmentVars, calls StartAsync, awaits Task.Delay(100), then checks procService is null or HasExited. An exit within 100ms, or a core that has not yet signaled alive, trips the guard.

Common situations: Core binary crashed on a bad config (most common); missing executable permissions or wrong file path; missing shared libraries; the 100ms delay is too short for a slow machine so the process appears not-yet-ready; wrong arguments/env-var format string (coreInfo.Arguments/Environment format failure); architecture mismatch.

Related errors


AI-assisted analysis of 2dust/v2rayN@e01717d832 (2026-08-13). Data as JSON: /api/errors/d84709c0e56c6ba3. Report an issue: GitHub.