{"record":{"id":"c21d5009c6067c48","repo":"vaxilu/x-ui","slug":"xray-is-not-running-c21d50","errorCode":null,"errorMessage":"xray is not running","messagePattern":"xray is not running","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"xray/process.go","lineNumber":227,"sourceCode":"\t\t}\n\t}()\n\n\tgo func() {\n\t\terr := cmd.Run()\n\t\tif err != nil {\n\t\t\tp.exitErr = err\n\t\t}\n\t}()\n\n\tp.refreshVersion()\n\tp.refreshAPIPort()\n\n\treturn nil\n}\n\nfunc (p *process) Stop() error {\n\tif !p.IsRunning() {\n\t\treturn errors.New(\"xray is not running\")\n\t}\n\treturn p.cmd.Process.Kill()\n}\n\nfunc (p *process) GetTraffic(reset bool) ([]*Traffic, error) {\n\tif p.apiPort == 0 {\n\t\treturn nil, common.NewError(\"xray api port wrong:\", p.apiPort)\n\t}\n\tconn, err := grpc.Dial(fmt.Sprintf(\"127.0.0.1:%v\", p.apiPort), grpc.WithInsecure())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer conn.Close()\n\n\tclient := statsservice.NewStatsServiceClient(conn)\n\tctx, cancel := context.WithTimeout(context.Background(), time.Second*10)\n\tdefer cancel()\n\trequest := &statsservice.QueryStatsRequest{","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/vaxilu/x-ui/blob/9c1be8c57a53953b47ee7c09a93554e73816f907/xray/process.go#L209-L245","documentation":"process.Stop in xray/process.go returns this error when IsRunning() is false, meaning there is no live process whose cmd.Process can be killed. It prevents calling Kill() on a nil or exited process handle, which would otherwise panic or be meaningless. It is the low-level counterpart of the service-level StopXray guard.","triggerScenarios":"Calling process.Stop() after xray already exited on its own (crash, config error), before Start() was ever called, or in a race where the process dies between IsRunning() and Kill().","commonSituations":"Panel stop/restart flows racing with a core crash; stopping during startup failure; scripts shutting down the panel while xray had already terminated.","solutions":["Check IsRunning() before calling Stop and treat already-stopped as success","Use the service-level StopXray/RestartXray which handle the locking for you","If xray should be running but isn't, check logs for why it exited and fix before restarting"],"exampleFix":"// before\nif err := p.Stop(); err != nil {\n    logger.Error(err)\n}\n// after\nif p.IsRunning() {\n    if err := p.Stop(); err != nil {\n        logger.Error(err)\n    }\n} // already stopped — nothing to do","handlingStrategy":"validation","validationCode":"if !p.IsRunning() {\n    return nil // nothing to stop\n}\nreturn p.Stop()","typeGuard":null,"tryCatchPattern":"if err := p.Stop(); err != nil {\n    if err.Error() == \"xray is not running\" {\n        logger.Debug(\"already stopped\")\n        return nil\n    }\n    return err\n}","preventionTips":["Check IsRunning() before Kill/Stop","Handle the race where the process exits between check and kill (recover from panic on Process.Kill)","Use the higher-level StopXray which already guards this","Monitor unexpected exits so stop calls arrive on live processes"],"tags":["xray","process-lifecycle"],"backgroundTag":"process-not-running","analyzedSha":"9c1be8c57a53953b47ee7c09a93554e73816f907","analyzedAt":"2026-09-02T18:46:17.308Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}