henrygd/beszel · error
invalid release digest %q
Error message
invalid release digest %q
What it means
verifyAssetChecksum validates the digest string published on the GitHub release asset before hashing the downloaded file. The digest must be in the form "<algorithm>:<hex-value>" (e.g. "sha256:abcd..."); strings.Cut must split on ":" and both halves must be non-empty. When the digest is missing the colon, empty, or only a bare hash without an algorithm prefix, the library rejects it outright rather than guessing.
Source
Thrown at internal/ghupdate/checksum.go:16
package ghupdate
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"os"
"strings"
)
func verifyAssetChecksum(path, digest string) error {
algorithm, expectedHex, ok := strings.Cut(digest, ":")
if !ok || algorithm == "" || expectedHex == "" {
return fmt.Errorf("invalid release digest %q", digest)
}
if !strings.EqualFold(algorithm, "sha256") {
return fmt.Errorf("unsupported release digest algorithm %q", algorithm)
}
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 {View on GitHub (pinned to b38fb7dafa)
Solutions
- Ensure releases are published through GitHub Releases so the API populates the asset digest field (GitHub generates sha256 digests automatically).
- If using a mirror or proxy, make sure it forwards the release JSON unchanged, including the assets' digest fields.
- Verify the digest string format is "sha256:<64 hex chars>" if constructing release metadata manually.
Example fix
// before (manually crafted digest) digest := "3f2a...c9" // bare hex, no algorithm prefix // after digest := "sha256:3f2a...c9" // "<algorithm>:<hex>" form expected by verifyAssetChecksum
Defensive patterns
Strategy: validation
Validate before calling
parts := strings.Split(asset.Digest, ":")
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
return errors.New("release asset digest is missing or malformed; cannot verify download")
} Try / catch
updated, err := ghupdate.Update(cfg)
if err != nil && strings.Contains(err.Error(), "invalid release digest") {
log.Printf("release digest missing/malformed (%v); skipping integrity check — update aborted", err)
} Prevention
- Publish releases through GitHub Releases so digests are auto-generated.
- Verify mirrors forward release JSON untouched.
- Unit-test release metadata with a digest-format assertion before shipping.
When it happens
Trigger: Calling ghupdate.Update (which calls update -> verifyAssetChecksum) when the release asset's Digest field from the GitHub/mirror API response is not in "algorithm:hex" form — empty string, plain hex hash with no "sha256:" prefix, trailing colon, or "sha256:" with no value.
Common situations: A custom release built and uploaded without GitHub's automatic checksum annotations; a proxy/mirror (e.g. gh.beszel.dev or a self-hosted mirror) that strips the digest field; running against a fork repo whose releases lack digests; an API mock or cached response that omitted the digest.
Related errors
- missing asset containing ${suffix}
- unsupported release digest algorithm %q
- invalid SHA-256 release digest %q
- release checksum mismatch: expected %s, got %s
- unsupported hash length: %d (expected 40 for SHA1 or 64 for
AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31).
Data as JSON: /api/errors/ea518448435e8fd4.
Report an issue: GitHub.