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

  1. Re-download; check the signature URL actually returns a valid base64 minisign signature (curl the .sig URL and inspect)
  2. Confirm the release/channel version publishes signatures — older versions may not
  3. 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

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


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)