{"record":{"id":"7d88bc9ec37ad83b","repo":"gitbutlerapp/gitbutler","slug":"final-installation-verification-failed","errorCode":null,"errorMessage":"Final installation verification failed","messagePattern":"Final installation verification failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/but-installer/src/install_linux.rs","lineNumber":109,"sourceCode":"    info(&format!(\n        \"Installing{} to {}...\",\n        channel\n            .map(|c| format!(\" channel {}\", c.display_name()))\n            .unwrap_or_default(),\n        install_bin_path.to_string_lossy(),\n    ));\n\n    // NOTE: Must copy rather than rename. Rename assumes source and dest are on the same mount\n    // point, but /tmp on Linux systems is very often an in-memory file system (tmpfs) and thus on\n    // a different mount point than persistent files\n    fs::copy(but_path, &install_bin_path)?;\n\n    let mut perms = fs::metadata(&install_bin_path)?.permissions();\n    perms.set_mode(0o755);\n    fs::set_permissions(&install_bin_path, perms)?;\n\n    if !validate_installed_binary(&install_bin_path) {\n        warn(\"Final installation verification failed\");\n\n        if let Some(but_backup) = but_backup {\n            warn(\"Attempting to restore backup\");\n            fs::rename(&but_backup, &install_bin_path)?;\n\n            if validate_installed_binary(&install_bin_path) {\n                info(\"Backup restored successfully, exiting ...\");\n                bail!(\"Installation failed but your previous installation was restored\");\n            } else {\n                bail!(\n                    \"Installation failed and backup restoration also failed - 'but' command may not work\"\n                );\n            }\n        } else {\n            bail!(\"Installation failed and no backup available to restore\");\n        }\n    } else if let Some(but_backup) = but_backup {\n        info(&format!(","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-installer/src/install_linux.rs#L91-L127","documentation":"After installing the Linux binary and setting 0o755 permissions, install_app validates the installed binary. If validate_installed_binary fails it warns 'Final installation verification failed' and attempts to restore the previous binary from backup. This catches installs that completed mechanically but produced a broken/non-runnable binary.","triggerScenarios":"Raised in install_app (download_and_install_app) when validate_installed_binary(&install_bin_path) returns false after fs::set_permissions — e.g. truncated download, wrong architecture binary, corrupted extraction, or exec bit/interpreter problems.","commonSituations":"Corrupted or truncated download from a flaky network/mirror; glibc too old for the shipped binary; x86_64 binary installed on aarch64; partial extraction of an archive; disk-full during extraction.","solutions":["Read the following log lines: if a backup exists the installer restores it and tells you whether the restore succeeded.","Re-download and re-run the installer; verify the archive checksum before installing.","Run the installed binary directly (./but --version) to see the real loader error (e.g. 'cannot execute binary file', 'GLIBC_2.xx not found').","Confirm the binary matches your architecture (uname -m) and OS; pick the correct release artifact.","Ensure sufficient free disk space and re-extract."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Validate download before install\nimport hashlib, subprocess\ndef verify(archive, expected_sha256, arch):\n    assert hashlib.sha256(open(archive,'rb').read()).hexdigest() == expected_sha256\n    out = subprocess.run(['file', archive], capture_output=True).stdout.decode()\n    assert arch in out, f'architecture mismatch: {out}'","typeGuard":null,"tryCatchPattern":"// Validate after install; roll back on failure\nif !validate_installed_binary(&install_bin_path) {\n    if let Some(backup) = &but_backup {\n        fs::rename(backup, &install_bin_path)?;\n        bail!(\"installation failed; previous version restored\");\n    }\n    bail!(\"installation failed validation and no backup exists\");\n}","preventionTips":["Verify release checksums before installing","Match the release artifact to your architecture and glibc version (uname -m; ldd --version)","Install on a filesystem with adequate free space","Run the binary with --version immediately after install to confirm it works"],"tags":["linux","installer","verification","binary"],"backgroundTag":"checksum-mismatch","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}