gitbutlerapp/gitbutler · warning
Could not remove quarantine attribute: {e} - macOS may show
Error message
Could not remove quarantine attribute: {e} - macOS may show security warnings What it means
The macOS installer strips the com.apple.quarantine extended attribute from the staged app bundle (remove_quarantine_recursive) so Gatekeeper does not treat the CLI-installed app as a blocked download. If stripping fails, the install continues — the consequence is deferred to the user: macOS may show 'app can't be opened because it is from an unidentified developer', resolved via System Settings > Privacy & Security > Allow Anyway.
Source
Thrown at crates/but-installer/src/install_macos.rs:104
.map(|c| format!(" channel {}", c.display_name()))
.unwrap_or_default(),
install_app.display()
));
// Clean up any leftover temp files from previous failed installations
let _ = fs::remove_dir_all(&install_app_new);
let _ = fs::remove_dir_all(&install_app_backup);
// Create Applications directory if it doesn't exist
fs::create_dir_all(home_dir.join("Applications"))?;
// Install to temporary location first
info("Installing to temporary location...");
copy_dir_all(app_dir, &install_app_new)?;
// Remove macOS quarantine attribute
if let Err(e) = remove_quarantine_recursive(&install_app_new) {
warn(&format!(
"Could not remove quarantine attribute: {e} - macOS may show security warnings"
));
info("If macOS blocks the app, go to System Settings > Privacy & Security and allow it");
}
// Create bin directory
let bin_dir = home_dir.join(".local/bin");
fs::create_dir_all(&bin_dir)?;
// Check for existing 'but' and detect channel switching
let but_symlink = bin_dir.join("but");
let but_new = bin_dir.join("but.new");
if but_symlink.exists() && !but_symlink.is_symlink() {
// 'but' exists but is not a symlink
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()View on GitHub (pinned to caf1f223d3)
Solutions
- If macOS blocks the app on first launch: System Settings > Privacy & Security > 'Allow Anyway'
- Strip the attribute manually: xattr -dr com.apple.quarantine ~/Applications/<App>.app
- Install Command Line Tools (xcode-select --install) and re-run the installer so removal succeeds
Defensive patterns
Strategy: fallback
Validate before calling
// Check whether the attribute is actually present before/after removal
std::process::Command::new("xattr")
.args(["-p", "com.apple.quarantine"])
.arg(&install_app_new)
.output()
.map(|o| o.status.success())
.unwrap_or(false); Try / catch
if let Err(e) = remove_quarantine_recursive(&install_app_new) {
warn(&format!("Could not remove quarantine attribute: {e} - macOS may show security warnings"));
info("If macOS blocks the app, go to System Settings > Privacy & Security and allow it");
} Prevention
- Install Command Line Tools before updating
- Keep app bundles user-owned in ~/Applications
- Always surface the 'Allow Anyway' guidance when quarantine stripping fails
When it happens
Trigger: remove_quarantine_recursive(&install_app_new) returns Err at crates/but-installer/src/install_macos.rs:104 — the xattr tooling is missing (no Xcode Command Line Tools), some files in the bundle are not writable by the user, or SIP or MDM policy restricts attribute changes.
Common situations: A fresh Mac without Command Line Tools; bundles containing root-owned files from a previous manual install; managed or sandboxed Macs restricting xattr.
Related errors
- New installation verification failed - 'but' binary cannot r
- Installation failed but your previous installation was resto
- Installation failed and backup restoration also failed - 'bu
- Installation failed and no backup available to restore
- {terminal_name} exited with non-zero status: {status_code}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/7480042b359b653a.
Report an issue: GitHub.