henrygd/beszel · error
failed to rename the current executable: %w
Error message
failed to rename the current executable: %w
What it means
During a self-update, ghupdate renames the currently running executable to a backup name before moving the newly downloaded binary into place. This error is wrapped from os.Rename when that rename of the old executable fails. The update is aborted before any replacement occurs, so the original binary is untouched.
Source
Thrown at internal/ghupdate/ghupdate.go:195
oldExec, err := os.Executable()
if err != nil {
return false, err
}
renamedOldExec := oldExec + ".old"
defer os.Remove(renamedOldExec)
newExec := filepath.Join(extractDir, p.config.ArchiveExecutable)
if _, err := os.Stat(newExec); err != nil {
// try again with an .exe extension
newExec = newExec + ".exe"
if _, fallbackErr := os.Stat(newExec); fallbackErr != nil {
return false, fmt.Errorf("the executable in the extracted path is missing or it is inaccessible: %v, %v", err, fallbackErr)
}
}
// rename the current executable
if err := os.Rename(oldExec, renamedOldExec); err != nil {
return false, fmt.Errorf("failed to rename the current executable: %w", err)
}
tryToRevertExecChanges := func() {
if revertErr := os.Rename(renamedOldExec, oldExec); revertErr != nil {
slog.Debug(
"Failed to revert executable",
slog.String("old", renamedOldExec),
slog.String("new", oldExec),
slog.String("error", revertErr.Error()),
)
}
}
// replace with the extracted binary
if err := os.Rename(newExec, oldExec); err != nil {
// If rename fails due to cross-device link, try copying instead
if isCrossDeviceError(err) {
if err := copyFile(newExec, oldExec); err != nil {View on GitHub (pinned to b38fb7dafa)
Solutions
- Ensure the directory containing the executable is writable by the user running the update (chmod/chown or run with sufficient privileges).
- Close programs locking the executable (antivirus scans, editors, running instances) and retry the update.
- Move the binary to a local writable filesystem instead of a read-only or network mount.
- As a workaround, manually download the new release and replace the binary yourself, then re-run.
Example fix
// before: update run as unprivileged user against a root-owned binary $ ./myapp update // error: failed to rename the current executable: permission denied // after: elevate or fix ownership first $ sudo chown $(whoami) $(which myapp) && sudo chmod u+w $(dirname $(which myapp)) $ ./myapp update
Defensive patterns
Strategy: validation
Validate before calling
execPath, err := os.Executable()
if err != nil { return err }
dir := filepath.Dir(execPath)
if info, err := os.Stat(dir); err != nil || !info.IsDir() { return fmt.Errorf("bad exec dir") }
if f, err := os.OpenFile(filepath.Join(dir, ".write-test"), os.O_CREATE|os.O_WRONLY, 0o644); err != nil {
return fmt.Errorf("directory not writable: %w", err)
} else { f.Close(); os.Remove(filepath.Join(dir, ".write-test")) } Type guard
func canRenameIn(dir string) bool {
fi, err := os.Stat(dir)
return err == nil && fi.IsDir()
} Try / catch
err := updater.Update(ctx, rel)
var updateErr *ghupdate.UpdateError
if errors.As(err, &updateErr) {
log.Error("self-update failed, binary unchanged", "err", err)
} else if err != nil { log.Error("update error", "err", err) } Prevention
- Install the binary in a user-writable, local (not NFS/read-only) directory.
- Don't run updates from cron/systemd units with stripped permissions unless intended.
- Exclude the binary directory from AV real-time scanning if updates fail intermittently.
- Check writability of the executable's directory before invoking update.
When it happens
Trigger: Calling Update (via the update function) when os.Rename(oldExec, renamedOldExec) returns an error — e.g. the executable file is locked, permission on the containing directory denies rename, or the filesystem does not permit the operation.
Common situations: Running the binary from a read-only mount or a directory without write permission; antivirus or backup software holding a lock on the executable (especially on Windows); running as a non-root user while the binary is owned by root; the executable sitting on a filesystem like some NFS mounts where rename over a running binary fails.
Related errors
- failed replacing the executable: %w
- failed to create update directory: %w
- data directory not found
- chmod: %w
- rename: %w
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/4e0a6d48df4d3d58.
Report an issue: GitHub.