gitbutlerapp/gitbutler · error

Installation failed but your previous installation was resto

Error message

Installation failed but your previous installation was restored

What it means

On Linux, after copying the new but binary into ~/.local/bin and chmod 755, install_linux runs 'but --version' to validate it. When that fails but a backup of the previous binary exists, the backup is renamed back and re-validated; if the restored copy passes, the installer bails with this message. Your previous version is intact and functional - the new one was rejected post-install.

Source

Thrown at crates/but-installer/src/install_linux.rs:117

    // NOTE: Must copy rather than rename. Rename assumes source and dest are on the same mount
    // point, but /tmp on Linux systems is very often an in-memory file system (tmpfs) and thus on
    // 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

  1. Confirm the old version still works: ~/.local/bin/but --version
  2. Diagnose why the new binary fails: run it directly from a temp dir and read the loader error ('No such file or directory' from ld.so means the ELF interpreter/libs are too new for the host)
  3. Check mount flags (findmnt ~/.local/bin -o OPTIONS) for noexec and disk space (df -h ~/.local /tmp)
  4. Stay on the last compatible version or upgrade the OS / build but from source
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-flight: the host must be able to load the new binary's shared libraries
let out = std::process::Command::new("ldd").arg(&downloaded_but).output()?;
let ldd = String::from_utf8_lossy(&out.stdout);
if ldd.contains("not found") {
    anyhow::bail!("host is missing shared libraries required by the new but binary");
}

Try / catch

match but_installer::run_installation_with_version(request, false) {
    Err(e) if e.to_string().contains("previous installation was restored") => {
        // system is functional on the old version; report and stop, do not retry blindly
        log::warn!("update rejected; previous but version is still active");
    }
    result => result,
}

Prevention

When it happens

Trigger: The newly downloaded binary fails to execute on this host - glibc older than the binary's requirements, wrong architecture, noexec mount on ~/.local/bin, truncated copy from a full disk, or endpoint security blocking newly written executables - while the previous binary still runs fine.

Common situations: Updating but on an old LTS distro (CentOS 7, Ubuntu 18.04) when a release raises its glibc baseline; corporate antivirus quarantining the new binary; ~/.local partition full during the copy.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/6f516a9ac85caaba. Report an issue: GitHub.