gitbutlerapp/gitbutler · error
Download failed, the download artifact could not be found…
Error message
Download failed, the download artifact could not be found. Most likely, the but CLI has not been published for the requested version.
What it means
`download_file` treats HTTP 403 from the release/download server as a special case: the artifact simply is not there for the requested version. It bails with this explicit message rather than a generic HTTP error, because GitButler's artifact host returns 403 (not 404) for missing files.
Solutions
- Verify the requested version is actually published (check the release on the GitButler releases page / latest.json).
- Retry later — artifacts may still be uploading for a fresh release.
- Omit the version pin and install/upgrade to the latest published version.
- Check whether your platform's artifact exists for that specific release; if not, build from source.
Example fix
// before
let cfg = Config::new_with_version(os, arch, VersionReq::parse("0.9.0")?, ...)?;
download_and_install_app(&cfg)?;
// after
let cfg = Config::new_with_version(os, arch, "latest".parse()?, ...)?; // or retry later
download_and_install_app(&cfg)?; Defensive patterns
Strategy: fallback
Validate before calling
let status = reqwest::blocking::Client::new()
.head(&artifact_url).send()?.status();
if status.as_u16() == 403 {
anyhow::bail!("artifact for version {} not published yet", version);
} Try / catch
match download_and_install_app(&config) {
Err(e) if e.to_string().contains("has not been published") => {
eprintln!("version not available; falling back to latest");
download_and_install_app(&Config::new_with_version(os, arch, "latest".parse()?, ...)?)?;
}
r => r?,
} Prevention
- Don't pin brand-new versions immediately after release; wait for artifacts to propagate.
- Check the release's published assets (per-platform) before requesting a specific version+platform.
- For automated upgrades, fall back to 'latest' when a pinned version is unavailable.
When it happens
Trigger: Calling download_and_install_app for a version whose platform artifact was never uploaded — e.g. `but upgrade` to a brand-new release before CI finished publishing, an unpublished/typo'd version string, or a platform (like linux-aarch64) excluded from that release.
Common situations: Upgrading immediately after a release announcement before artifacts propagate; pinning a specific old/new version that lacks your platform's build; corporate proxies rewriting 404s into 403s.
Related errors
- Download failed with HTTP status
- Download of failed with HTTP status
- Failed to fetch release information for version
- Anthropic API error ( )
- API returned version
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/3060d58255a79885.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-installer/src/download.rs:125
// Check if we had a write error
if let Some(io_err) = write_error.borrow_mut().take() {
// Clear progress line before showing error
crate::ui::println_empty();
return Err(io_err).context("Failed to write downloaded data");
}
// If perform failed for other reasons, propagate that error
perform_result.with_context(|| format!("Failed to download from {url}"))?;
}
// Clear progress line
crate::ui::println_empty();
let response_code = easy
.response_code()
.context("Failed to get response code")?;
if response_code == 403 {
bail!(
"Download failed, the download artifact could not be found. Most likely, the but CLI has not been published for the requested version."
)
} else if response_code != 200 {
bail!("Download failed with HTTP status: {response_code}");
}
// Validate the effective URL after following redirects
// This protects against malicious redirects to untrusted domains or insecure protocols
let effective_url = easy
.effective_url()
.context("Failed to get effective URL")?
.ok_or_else(|| anyhow!("Effective URL is missing"))?;
crate::release::validate_download_url(effective_url)
.with_context(|| format!("Download was redirected to an untrusted URL: {effective_url}"))?;
Ok(())
}View on GitHub (pinned to 58e5313667)