gitbutlerapp/gitbutler · error
is not from a trusted GitButler domain
Error message
{url_type} is not from a trusted GitButler domain: {url} What it means
After the HTTPS check, validate_gitbutler_url parses the URL and checks its host against a domain allowlist predicate (validate_api_url and validate_download_url each supply one). This error means the URL points at a host outside GitButler's trusted domains, blocking potential malicious redirects or misconfiguration.
Solutions
- Use the official GitButler API/download domains as configured by the installer
- Fix typos in a custom-configured host
- Investigate if a redirect changed the host unexpectedly (possible security issue)
- If you legitimately need another host, the allowlist predicates must be updated upstream
Example fix
null
Defensive patterns
Strategy: validation
Validate before calling
fn is_trusted_host(url: &str) -> bool {
url::Url::parse(url).ok()
.and_then(|u| u.host_str().map(|h| h.to_string()))
.map(|h| h == "api.gitbutler.com" || h.ends_with(".gitbutler.com"))
.unwrap_or(false)
} Try / catch
match result {
Err(e) if e.to_string().contains("trusted GitButler domain") => {
// treat as potential security issue: log host, refuse custom mirrors
}
other => other?,
} Prevention
- Only use official GitButler domains
- Double-check hostname spelling in any custom config
- Treat unexpected host changes after redirects as security signals
- Keep the domain allowlist maintained upstream
When it happens
Trigger: A download/API URL whose hostname is not in the allowlist: custom mirror, attacker-controlled redirect target, typo'd domain (e.g. gitbutlr.com), or test/staging host.
Common situations: Open-redirect responses from the release API, DNS hijacking or proxy rewriting hosts, developer configuring an unofficial mirror, DNS rebinding during incident testing.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- must use HTTPS
- Clone remote URL contains unsupported control characters
- must be an HTTP or HTTPS URL
- Invalid path scheme
- Refusing to remove label with degenerate name
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/851647a63168ab7f.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-installer/src/release.rs:116
url: &str,
url_type: &str,
is_host_valid: impl Fn(&str) -> bool,
) -> Result<()> {
// Only allow HTTPS URLs
if !url.starts_with("https://") {
bail!("{url_type} must use HTTPS: {url}");
}
// Extract host from URL
let url_parsed =
url::Url::parse(url).with_context(|| format!("Invalid {} URL", url_type.to_lowercase()))?;
let host = url_parsed
.host_str()
.ok_or_else(|| anyhow!("No host in {} URL", url_type.to_lowercase()))?;
// Validate host using the provided predicate
if !is_host_valid(host) {
bail!("{url_type} is not from a trusted GitButler domain: {url}");
}
Ok(())
}
/// Validates that an API URL is from the trusted API domain.
///
/// API endpoints should only be served from app.gitbutler.com to prevent
/// redirecting API requests to other subdomains.
pub(crate) fn validate_api_url(url: &str) -> Result<()> {
validate_gitbutler_url(url, "API URL", |host| host == "app.gitbutler.com")
}
/// Validates that a download URL is from a trusted GitButler domain.
///
/// This is more permissive than API validation, allowing downloads from:
/// - `gitbutler.com` (root domain)
/// - Any `*.gitbutler.com` subdomain (e.g., `releases.gitbutler.com`, `cdn.gitbutler.com`)View on GitHub (pinned to 58e5313667)