{"record":{"id":"88e8bd468521df6d","repo":"MHSanaei/3x-ui","slug":"xray-is-not-running","errorCode":null,"errorMessage":"xray is not running","messagePattern":"xray is not running","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/web/service/xray.go","lineNumber":876,"sourceCode":"\t}\n\n\tif !changed {\n\t\treturn routerCfg\n\t}\n\n\tparsed[\"rules\"] = activeRules\n\tout, err := json.Marshal(parsed)\n\tif err != nil {\n\t\treturn routerCfg\n\t}\n\treturn out\n}\n\n// GetXrayTraffic fetches the current traffic statistics from the running Xray process.\nfunc (s *XrayService) GetXrayTraffic() ([]*xray.Traffic, []*xray.ClientTraffic, error) {\n\tprocess := currentXrayProcess()\n\tif process == nil || !process.IsRunning() {\n\t\terr := errors.New(\"xray is not running\")\n\t\tlogger.Debug(\"Attempted to fetch Xray traffic, but Xray is not running:\", err)\n\t\treturn nil, nil, err\n\t}\n\tapiPort := process.GetAPIPort()\n\tif err := s.xrayAPI.Init(apiPort); err != nil {\n\t\tlogger.Debug(\"Failed to initialize Xray API:\", err)\n\t\treturn nil, nil, err\n\t}\n\tdefer s.xrayAPI.Close()\n\n\ttraffic, clientTraffic, err := s.xrayAPI.GetTraffic()\n\tif err != nil {\n\t\tlogger.Debug(\"Failed to fetch Xray traffic:\", err)\n\t\treturn nil, nil, err\n\t}\n\treturn traffic, clientTraffic, nil\n}\n","sourceCodeStart":858,"sourceCodeEnd":894,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/service/xray.go#L858-L894","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"traffic, clientTraffic, err := xrayService.GetXrayTraffic()\nif err != nil && strings.Contains(err.Error(), \"xray is not running\") {\n    // core is down: skip this poll instead of surfacing an error\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := xrayService.GetXrayTraffic(); err != nil {\n    if strings.Contains(err.Error(), \"xray is not running\") {\n        log.Debug(\"skipping traffic poll: core down\")\n        return\n    }\n    return err\n}","preventionTips":["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."],"tags":["xray","process","grpc","lifecycle"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}