gitbutlerapp/gitbutler · warning · anyhow::Error
Request failed: {e}
Error message
Request failed: {e} What it means
The reqwest POST to the update server (https://app.gitbutler.com/updates by default) failed at the transport layer — DNS resolution, TCP connect, TLS handshake, or the 30-second timeout fired. The error string chains the underlying reqwest error with the specific cause.
Source
Thrown at crates/but-update/src/check.rs:125
.default_headers(headers)
.timeout(REQUEST_TIMEOUT)
.build()?;
let url = url_override.unwrap_or(UPDATES_CHECK_URL).to_string();
let result = std::thread::spawn(move || -> anyhow::Result<CheckUpdateStatus> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.map_err(|e| anyhow::anyhow!("Failed to create runtime: {e}"))?;
runtime.block_on(async {
let response = client
.post(url)
.json(&request_body)
.send()
.await
.map_err(|e| anyhow::anyhow!("Request failed: {e}"))?
.error_for_status()
.map_err(|e| anyhow::anyhow!("Server returned error: {e}"))?;
let update_info = response
.json::<CheckUpdateStatus>()
.await
.map_err(|e| anyhow::anyhow!("Failed to parse response: {e}"))?;
Ok(update_info)
})
})
.join()
.map_err(|_| anyhow::anyhow!("Update check thread panicked"))?;
// Save to cache (convert to but_db types)
if let Ok(status) = &result {
let now = chrono::Utc::now();
View on GitHub (pinned to caf1f223d3)
Solutions
- Verify connectivity to https://app.gitbutler.com/updates (curl -I) from the same machine
- Configure proxy env vars (HTTPS_PROXY) if a corporate proxy is required
- Treat as non-fatal: update checks are optional; skip/retry later when back online
Defensive patterns
Strategy: retry
Validate before calling
// preflight connectivity before the check
if !std::net::TcpStream::connect_timeout(&"app.gitbutler.com:443".to_socket_addrs()?.next().unwrap(), std::time::Duration::from_secs(3)).is_ok() {
return Ok(None); // offline: use cached update info instead
} Try / catch
let mut attempt = 0;
loop {
match check_status(app, settings, cache) {
Err(e) if e.to_string().contains("Request failed") && attempt < 2 => { attempt += 1; std::thread::sleep(backoff(attempt)); }
other => break other,
}
} Prevention
- Honor offline state: skip checks when the OS reports no connectivity
- Configure HTTPS_PROXY in proxied environments before reporting bugs
- Keep update-check intervals sparse; every failure is already retried on the next app start
When it happens
Trigger: check_status() with no network connectivity, a proxy/firewall blocking app.gitbutler.com, DNS failure, or a response slower than the REQUEST_TIMEOUT of 30s.
Common situations: Offline or captive-portal networks; corporate proxies that MITM TLS; transient outages of the update endpoint; CI runners without egress.
Related errors
- Server returned error: {e}
- Download of {url} failed with HTTP status: {response_code}
- Download failed with HTTP status: {response_code}
- Failed to create runtime: {e}
- Failed to parse response: {e}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/d2594cb133c3e7ce.
Report an issue: GitHub.