henrygd/beszel · critical
release checksum mismatch: expected %s, got %s
Error message
release checksum mismatch: expected %s, got %s
What it means
The computed SHA-256 of the downloaded asset does not match the digest published on the release. The library deliberately fails closed: a mismatch means the download is corrupt, incomplete, or has been tampered with, so the update is aborted before extraction and the binary is never replaced. The error shows both the expected and actual hex digests for comparison.
Source
Thrown at internal/ghupdate/checksum.go:39
expected, err := hex.DecodeString(expectedHex)
if err != nil || len(expected) != sha256.Size {
return fmt.Errorf("invalid SHA-256 release digest %q", digest)
}
file, err := os.Open(path)
if err != nil {
return fmt.Errorf("failed to open release for checksum verification: %w", err)
}
defer file.Close()
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
return fmt.Errorf("failed to calculate release checksum: %w", err)
}
actual := hash.Sum(nil)
if !bytes.Equal(actual, expected) {
return fmt.Errorf("release checksum mismatch: expected %s, got %s", expectedHex, hex.EncodeToString(actual))
}
return nil
}
View on GitHub (pinned to b38fb7dafa)
Solutions
- Simply retry the update — transient truncation during download is the most common cause.
- Bypass any proxy/CDN cache or wait for the mirror to sync; try with UseMirror toggled to fetch from the other source.
- Compare the 'got' hash against the official sha256sum published with the release to distinguish corruption from tampering.
- If mismatches persist from your network, download the asset manually, verify its hash, and investigate the middlebox rewriting content.
Defensive patterns
Strategy: try-catch
Try / catch
updated, err := ghupdate.Update(cfg)
if err != nil && strings.Contains(err.Error(), "release checksum mismatch") {
log.Printf("download integrity check failed (%v); do NOT install manually — retry via a trusted network or wait for mirror sync", err)
} Prevention
- Never bypass or disable checksum verification to force an update.
- Retry on a trusted network; caches and proxies are the usual culprit.
- Keep mirrors in sync with upstream releases before pointing clients at them.
- Treat persistent mismatches as a security incident and compare against the official sha256sum.
When it happens
Trigger: ghupdate.Update -> update -> downloadFile -> verifyAssetChecksum when the downloaded archive's hash differs from the release digest: truncated/interrupted download that still returned HTTP 200, a proxy/CDN serving stale or modified content, a MITM, or the mirror serving an outdated asset while the digest points to a newer build.
Common situations: Corporate proxies caching an old asset; gh.beszel.dev or a custom mirror lagging behind GitHub; unstable network dropping bytes from a large tar.gz; an attacker substituting binaries (the case this check exists for).
Related errors
- invalid release digest %q
- unsupported release digest algorithm %q
- hub not verified
- missing asset containing ${suffix}
- fingerprint mismatch
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/97b56ee9063f525f.
Report an issue: GitHub.