gitbutlerapp/gitbutler · critical
Installation failed and backup restoration also failed - 'bu
Error message
Installation failed and backup restoration also failed - 'but' command may not work
What it means
Worst-case Linux rollback: the new binary failed post-install validation, the backup was renamed back into ~/.local/bin/but, but the restored binary also fails 'but --version'. The installer gives up and warns the but command may not work. This is a system-level execution problem, not a bad artifact - two independent binaries fail to run.
Source
Thrown at crates/but-installer/src/install_linux.rs:119
// a different mount point than persistent files
fs::copy(but_path, &install_bin_path)?;
let mut perms = fs::metadata(&install_bin_path)?.permissions();
perms.set_mode(0o755);
fs::set_permissions(&install_bin_path, perms)?;
if !validate_installed_binary(&install_bin_path) {
warn("Final installation verification failed");
if let Some(but_backup) = but_backup {
warn("Attempting to restore backup");
fs::rename(&but_backup, &install_bin_path)?;
if validate_installed_binary(&install_bin_path) {
info("Backup restored successfully, exiting ...");
bail!("Installation failed but your previous installation was restored");
} else {
bail!(
"Installation failed and backup restoration also failed - 'but' command may not work"
);
}
} else {
bail!("Installation failed and no backup available to restore");
}
} else if let Some(but_backup) = but_backup {
info(&format!(
"Removing backup at {}",
but_backup.to_string_lossy()
));
fs::remove_file(&but_backup)?;
}
Ok(())
}
View on GitHub (pinned to caf1f223d3)
Solutions
- Run ~/.local/bin/but --version directly and read the exact error (ENOEXEC, missing interpreter, 'Permission denied')
- Check for noexec: findmnt -T ~/.local/bin/but -o OPTIONS; remount without noexec or move the bin dir
- Restore endpoint-security allowance for ~/.local/bin/but, then reinstall
- If unrecoverable, manually download the tarball and place the binary in an exec-mounted PATH directory
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the install destination can execute binaries before installing
use std::os::unix::fs::PermissionsExt;
let bin_dir = home.join(".local/bin");
std::fs::create_dir_all(&bin_dir)?;
let probe = bin_dir.join(".exec-probe");
std::fs::write(&probe, "#!/bin/sh\nexit 0\n")?;
std::fs::set_permissions(&probe, std::fs::Permissions::from_mode(0o755))?;
let exec_ok = std::process::Command::new(&probe).status().is_ok_and(|s| s.success());
std::fs::remove_file(&probe)?;
anyhow::ensure!(exec_ok, "install dir is not executable (noexec mount?)"); Try / catch
if let Err(e) = but_installer::run_installation_with_version(request, false) {
if e.to_string().contains("backup restoration also failed") {
// both binaries fail: repair the environment (noexec mount, permissions, AV),
// then reinstall from scratch
repair_environment()?;
return but_installer::run_installation_with_version(
but_installer::VersionRequest::Release, false);
}
return Err(e);
} Prevention
- Never mount ~/.local/bin noexec
- Keep a copy of the last working but tarball for manual recovery
- Probe binary execution in the install dir before running updates
When it happens
Trigger: Both old and new binaries fail to execute: ~/.local/bin mounted noexec, the system's glibc or dynamic loader broke independently (OS upgrade in progress), disk corruption, or endpoint security quarantining every newly written executable including the restore.
Common situations: noexec home partitions in hardened setups; distro upgrade replacing glibc mid-update; security software treating the rename-back as a new file and blocking it.
Related errors
- Installation failed but your previous installation was resto
- Installation failed and no backup available to restore
- Installation failed and backup restoration also failed - 'bu
- Download of {url} failed with HTTP status: {response_code}
- New installation verification failed - 'but' binary cannot r
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/52e1774513d8081f.
Report an issue: GitHub.