gitbutlerapp/gitbutler · critical
Failed to initialize signature verifier
Error message
Failed to initialize signature verifier: {e} What it means
verify_signature() uses minisign (public_key.verify_stream) to initialize a streaming signature verifier for a downloaded artifact. The error wraps any failure from creating that verifier — meaning the signature data itself could not be accepted by the verifier (malformed/undecodable signature), not that content mismatched.
Solutions
- Re-download; check the signature URL actually returns a valid base64 minisign signature (curl the .sig URL and inspect)
- Confirm the release/channel version publishes signatures — older versions may not
- Check that proxies/CDNs aren't substituting error pages for the .sig asset
Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the signature payload before verification
if sig_b64.trim().is_empty() {
anyhow::bail!("signature file is empty; refusing to verify");
}
let decoded = base64::decode(sig_b64.trim())?;
anyhow::ensure!(decoded.starts_with(b"untrusted comment:"), "not a minisign signature"); Try / catch
if let Err(e) = verify_signature(&file, &sig, &dir) {
if e.to_string().contains("initialize signature verifier") {
eprintln!("Signature asset invalid — re-download or use a newer release");
}
return Err(e);
} Prevention
- Fetch signatures only from the official release domain (validate_download_url)
- Never verify against an empty or HTML-body response; check content-type
- Prefer releases known to publish signatures for all assets
When it happens
Trigger: Calling download_and_install_app (or the test_verify_signature_empty test path) where the base64 signature downloaded from the release server fails to decode or initialize in verify_stream — e.g. empty, truncated, or wrongly-encoded signature file.
Common situations: Old releases whose signature assets are missing or in a legacy format; a CDN/proxy returning an HTML error page instead of the .sig file; network truncation of the signature.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- Signature is empty - refusing to verify without a valid…
- Signature verification failed - the download may have been…
- BUG: Sensitive data cannot be serialized - it needs to be…
- Download failed, the download artifact could not be found…
- Download failed with HTTP status
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/94362b7702b2da19.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-installer/src/install.rs:74
// Write signature to temp file for minisign to parse
let signature_file = temp_dir.join("signature.minisig");
fs::write(&signature_file, &signature_bytes)?;
// Read it back as a string (minisign signatures are text files)
let signature_str =
fs::read_to_string(&signature_file).context("Failed to read signature file as string")?;
// Parse the signature
let signature =
minisign_verify::Signature::decode(&signature_str).context("Failed to parse signature")?;
// Use streaming verification to avoid loading entire file into memory
let mut file =
File::open(installable).context("Failed to open installable for verification")?;
let mut verifier = public_key
.verify_stream(&signature)
.map_err(|e| anyhow!("Failed to initialize signature verifier: {e}"))?;
// Read and verify file in 64KB chunks
let mut buffer = [0u8; 65536];
loop {
let bytes_read = file.read(&mut buffer)?;
if bytes_read == 0 {
break;
}
verifier.update(&buffer[..bytes_read]);
}
// Finalize verification
verifier.finalize().map_err(|e| {
anyhow!("Signature verification failed - the download may have been tampered with: {e}")
})?;
ui::info("Signature verification passed");
Ok(())View on GitHub (pinned to 58e5313667)