MHSanaei/3x-ui · info
xray is not running
Error message
xray is not running
What it means
process.Stop() first checks IsRunning(); if the core is not alive it returns this error instead of signaling. It means by the time Stop ran, the child had already exited (crash or external kill) or was never started. Nothing was signaled — the caller must decide whether that matters.
Source
Thrown at internal/xray/process.go:666
if runtime.GOOS == "windows" {
errStr := strings.ToLower(err.Error())
if strings.Contains(errStr, "exit status 1") {
p.setExitErr(err)
return
}
}
logger.Error("Failure in running xray-core:", err)
p.setExitErr(err)
if OnCrash != nil {
OnCrash(err)
}
}
// Stop terminates the running Xray process.
func (p *process) Stop() error {
if !p.IsRunning() {
return errors.New("xray is not running")
}
p.intentionalStop.Store(true)
// Snapshot cmd once, then run the blocking Signal/Kill/Wait on the local copy
// without holding the lock.
p.mu.RLock()
cmd := p.cmd
p.mu.RUnlock()
if cmd == nil || cmd.Process == nil {
return errors.New("xray is not running")
}
// Remove temporary config file used for test runs so main config is never touched
if p.configPath != "" {
if p.configPath != GetConfigPath() {
// Check if file exists before removing
if _, err := os.Stat(p.configPath); err == nil {
_ = os.Remove(p.configPath)View on GitHub (pinned to ad32144c42)
Solutions
- Treat as benign when the goal is 'make sure it is stopped' — that state already holds.
- If a crash is suspected, read the xray log and the exit error recorded via setExitErr to find the root cause.
- Serialize stop/start flows through XrayService's lock to avoid racing the crash-restart handler.
Defensive patterns
Strategy: try-catch
Try / catch
if err := p.Stop(); err != nil {
if strings.Contains(err.Error(), "xray is not running") {
return nil // already stopped
}
return err
} Prevention
- Treat stop as idempotent in all orchestration code.
- If the core was expected alive, pull the exit error set by setExitErr / crash logs to find why it died first.
When it happens
Trigger: StopXray racing a core crash; stopping after someone already stopped; stopping a process object whose cmd was never started (fresh instance).
Common situations: Panel shutdown after xray crashed on bad config; double-stop sequences; orchestrating restarts where the crash handler already reaped the child.
Related errors
- traffic writer stopped before write completed
- xray is not running
- xray is already running
- local xray is not running
- invalid metric (unknown metric)
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/7bc0ad0fa7e32075.
Report an issue: GitHub.