{"record":{"id":"8881547224015497","repo":"MHSanaei/3x-ui","slug":"failed-to-start-panel-update-job-w","errorCode":null,"errorMessage":"failed to start panel update job: %w","messagePattern":"failed to start panel update job: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/web/service/panel/panel.go","lineNumber":290,"sourceCode":"\t\t} else {\n\t\t\tlogger.Infof(\"started panel update job via systemd-run unit %s\", unitName)\n\t\t\tlaunched = true\n\t\t\treturn runID, nil\n\t\t}\n\t}\n\n\tcmd := exec.CommandContext(context.Background(), bash, \"-lc\", updateScript)\n\tcmd.Env = append(os.Environ(),\n\t\t\"XUI_MAIN_FOLDER=\"+mainFolder,\n\t\t\"XUI_SERVICE=\"+serviceFolder,\n\t\t\"XUI_UPDATE_TAG=\"+updateTag,\n\t\trunIDEnv,\n\t\tstatusFileEnv,\n\t)\n\tsetDetachedProcess(cmd)\n\tif err := cmd.Start(); err != nil {\n\t\t_ = os.Remove(scriptPath)\n\t\treturn 0, fmt.Errorf(\"failed to start panel update job: %w\", err)\n\t}\n\tif err := cmd.Process.Release(); err != nil {\n\t\tlogger.Warning(\"failed to release panel update process:\", err)\n\t}\n\tlogger.Infof(\"started panel update job with pid %d\", cmd.Process.Pid)\n\trecordUpdatePID(cmd.Process.Pid)\n\tlaunched = true\n\treturn runID, nil\n}\n\n// acquireUpdateSlot claims the single in-flight-update slot for runID. It\n// refuses while another run is genuinely still in flight, but grants the\n// slot immediately once that run's own status file reports a terminal\n// result (success or failure) -- a fast failure shouldn't force the next\n// attempt to wait out updateStaleAfter for no reason. Past updateStaleAfter\n// with no terminal status yet, it grants the slot anyway UNLESS the process\n// we recorded (updatePID) is confirmed still alive, so a merely-slow run\n// isn't mistaken for a crashed one; past updateHardCeiling it grants the","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/MHSanaei/3x-ui/blob/ad32144c42455696ea9f14e12168beac3e25f5d2/internal/web/service/panel/panel.go#L272-L308","documentation":"Fallback path when systemd-run is unavailable: the updater script is launched as a detached process (setDetachedProcess) with bash -lc. cmd.Start() failing here means the OS could not fork/exec at all — most often resource exhaustion (fork: cannot allocate memory, fork: retry), a full disk affecting temp writes, or bash disappearing between LookPath and Start.","triggerScenarios":"Panel update attempted on a memory-starved VPS (fork fails), or in a container at its pids/memory cgroup limit, so spawning the detached updater fails immediately; scriptPath is cleaned up and the run aborted.","commonSituations":"Small VPS with heavy xray load hitting cgroup memory limits exactly when updating; containers with a low pids-max; very high process count.","solutions":["Free resources: stop xray temporarily or raise the container/service memory & pids limits, then retry the update","Check dmesg/journal for 'fork: cannot allocate memory' or cgroup OOM events","If persistent, run the updater script manually from a root shell"],"exampleFix":"# container at limits\ndocker update --memory 1g --pids-limit 512 <panel-container>\n# then retry the web update; or run manually:\nbash -lc \"$(curl -fsSL <updater-url>)\"","handlingStrategy":"retry","validationCode":"// precheck spawn capacity\nif err := syscall.ForkExec(\"/bin/true\", nil, &syscall.ProcAttr{}); err != nil {\n    // system cannot fork right now; free resources before updating\n}","typeGuard":null,"tryCatchPattern":"_, err := panelService.StartUpdate(false)\nif err != nil && strings.Contains(err.Error(), \"failed to start panel update job\") && strings.Contains(err.Error(), \"fork\") {\n    // resource exhaustion: free memory/pids, then retry once\n}","preventionTips":["Raise container memory/pids limits before triggering updates","Stop xray temporarily on memory-constrained hosts during updates"],"tags":["updates","panel-update","resources","process","linux"],"backgroundTag":null,"analyzedSha":"ad32144c42455696ea9f14e12168beac3e25f5d2","analyzedAt":"2026-08-15T11:13:23.905Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}