MHSanaei/3x-ui · warning
xray is not running
Error message
xray is not running
What it means
GetXrayTraffic asks the running Xray core for live traffic counters over its gRPC API; it first resolves the current process and returns this error when currentXrayProcess() is nil or IsRunning() is false. It is a guard for 'no live core to query', not a gRPC failure. Common during startup, after a crash, or after a manual stop.
Source
Thrown at internal/web/service/xray.go:876
}
if !changed {
return routerCfg
}
parsed["rules"] = activeRules
out, err := json.Marshal(parsed)
if err != nil {
return routerCfg
}
return out
}
// GetXrayTraffic fetches the current traffic statistics from the running Xray process.
func (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, []*xray.ClientTraffic, error) {
process := currentXrayProcess()
if process == nil || !process.IsRunning() {
err := errors.New("xray is not running")
logger.Debug("Attempted to fetch Xray traffic, but Xray is not running:", err)
return nil, nil, err
}
apiPort := process.GetAPIPort()
if err := s.xrayAPI.Init(apiPort); err != nil {
logger.Debug("Failed to initialize Xray API:", err)
return nil, nil, err
}
defer s.xrayAPI.Close()
traffic, clientTraffic, err := s.xrayAPI.GetTraffic()
if err != nil {
logger.Debug("Failed to fetch Xray traffic:", err)
return nil, nil, err
}
return traffic, clientTraffic, nil
}
View on GitHub (pinned to ad32144c42)
Solutions
- Check whether xray is expected to run at all (manually stopped / sub-node) — if so, ignore the error.
- Inspect Xray log (log folder per XUI_LOG_FOLDER) and the crash event for why the core exited; fix config and restart.
- Retry after the startup/restart window: poll IsRunning before retrying the traffic fetch.
Defensive patterns
Strategy: validation
Validate before calling
traffic, clientTraffic, err := xrayService.GetXrayTraffic()
if err != nil && strings.Contains(err.Error(), "xray is not running") {
// core is down: skip this poll instead of surfacing an error
return nil
} Try / catch
if _, _, err := xrayService.GetXrayTraffic(); err != nil {
if strings.Contains(err.Error(), "xray is not running") {
log.Debug("skipping traffic poll: core down")
return
}
return err
} Prevention
- Poll only after startup reports the core running; gate dashboard traffic fetches on process status.
- Watch the xray.crash eventbus event to detect a dead core before the next poll hits this guard.
When it happens
Trigger: Calling XrayService.GetXrayTraffic (panel dashboard traffic refresh) before the first StartXray completes, after StopXray, or after the xray-core child process exited/crashed and the crash handler has not yet restarted it.
Common situations: Dashboard opened right after panel boot; xray-core crashed on a bad config (check the xray.crash eventbus event and xray logs); running on a sub-node where the local core is intentionally stopped.
Related errors
- local xray is not running
- xray is already running
- xray is not running
- missing required user field %q
- traffic writer stopped before write completed
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/88e8bd468521df6d.
Report an issue: GitHub.