MHSanaei/3x-ui · error
failed to start panel update job: %w
Error message
failed to start panel update job: %w
What it means
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.
Source
Thrown at internal/web/service/panel/panel.go:290
} else {
logger.Infof("started panel update job via systemd-run unit %s", unitName)
launched = true
return runID, nil
}
}
cmd := exec.CommandContext(context.Background(), bash, "-lc", updateScript)
cmd.Env = append(os.Environ(),
"XUI_MAIN_FOLDER="+mainFolder,
"XUI_SERVICE="+serviceFolder,
"XUI_UPDATE_TAG="+updateTag,
runIDEnv,
statusFileEnv,
)
setDetachedProcess(cmd)
if err := cmd.Start(); err != nil {
_ = os.Remove(scriptPath)
return 0, fmt.Errorf("failed to start panel update job: %w", err)
}
if err := cmd.Process.Release(); err != nil {
logger.Warning("failed to release panel update process:", err)
}
logger.Infof("started panel update job with pid %d", cmd.Process.Pid)
recordUpdatePID(cmd.Process.Pid)
launched = true
return runID, nil
}
// acquireUpdateSlot claims the single in-flight-update slot for runID. It
// refuses while another run is genuinely still in flight, but grants the
// slot immediately once that run's own status file reports a terminal
// result (success or failure) -- a fast failure shouldn't force the next
// attempt to wait out updateStaleAfter for no reason. Past updateStaleAfter
// with no terminal status yet, it grants the slot anyway UNLESS the process
// we recorded (updatePID) is confirmed still alive, so a merely-slow run
// isn't mistaken for a crashed one; past updateHardCeiling it grants theView on GitHub (pinned to ad32144c42)
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
Example fix
# container at limits docker update --memory 1g --pids-limit 512 <panel-container> # then retry the web update; or run manually: bash -lc "$(curl -fsSL <updater-url>)"
Defensive patterns
Strategy: retry
Validate before calling
// precheck spawn capacity
if err := syscall.ForkExec("/bin/true", nil, &syscall.ProcAttr{}); err != nil {
// system cannot fork right now; free resources before updating
} Try / catch
_, err := panelService.StartUpdate(false)
if err != nil && strings.Contains(err.Error(), "failed to start panel update job") && strings.Contains(err.Error(), "fork") {
// resource exhaustion: free memory/pids, then retry once
} Prevention
- Raise container memory/pids limits before triggering updates
- Stop xray temporarily on memory-constrained hosts during updates
When it happens
Trigger: 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.
Common situations: Small VPS with heavy xray load hitting cgroup memory limits exactly when updating; containers with a low pids-max; very high process count.
Related errors
- panel web update is supported only on Linux installations
- failed to start panel update job: %w: %s
- a panel update is already in progress
- bash is required to run the panel updater: %w
- download panel updater: %w
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/8881547224015497.
Report an issue: GitHub.