xtekky/gpt4free · critical
sha256 mismatch: got %s, want %s
Error message
sha256 mismatch: got %s, want %s
What it means
verifyRuntime in g4f-go/download.go hashes the downloaded archive with sha256 and compares (case-insensitively) against spec.SHA256 pinned in runtime.json. A mismatch means the bytes on disk are not the bytes the manifest author signed — corrupted download, silently altered artifact, or a stale manifest hash after the artifact changed.
Source
Thrown at g4f-go/download.go:169
}
// verifyRuntime validates sha256 when pinned in the manifest.
func verifyRuntime(cachePath string, spec *RuntimeSpec) error {
if spec.SHA256 == "" {
return nil // unpinned; trust size/transport
}
f, err := os.Open(cachePath)
if err != nil {
return err
}
defer f.Close()
h := sha256.New()
if _, err := io.Copy(h, f); err != nil {
return err
}
got := hex.EncodeToString(h.Sum(nil))
if !strings.EqualFold(got, spec.SHA256) {
return fmt.Errorf("sha256 mismatch: got %s, want %s", got, spec.SHA256)
}
fmt.Println("runtime: sha256 verified")
return nil
}
// copyWithProgress streams r into w while printing a \r-updated progress bar.
func copyWithProgress(w io.Writer, r io.Reader, total int64, start time.Time) (int64, error) {
buf := make([]byte, 256*1024)
var written int64
lastPrint := time.Time{}
for {
n, err := r.Read(buf)
if n > 0 {
if _, werr := w.Write(buf[:n]); werr != nil {
return written, werr
}
written += int64(n)
// Throttle progress output to ~5 updates/sec.View on GitHub (pinned to 973504e177)
Solutions
- Compute the actual hash (sha256sum <cachePath>) and compare with runtime.json — if the official artifact matches your download, the manifest hash is stale: update it
- Delete the cached archive and re-download to rule out corruption in transit
- Download only from the official URL in the upstream repo; distrust mirrors after a mismatch
- If you publish runtimes yourself, always regenerate both size and sha256 together when the artifact changes
Example fix
# before # sha256 mismatch: got ab12..., want cd34... # after sha256sum .g4f-runtime/runtime-*.tar.gz # got # verify against the official release notes; if the download is the official one: # edit runtime.json -> replace sha256 with the verified value rm .g4f-runtime/runtime-*.tar.gz # force clean re-download if corrupted
Defensive patterns
Strategy: validation
Validate before calling
sum, err := sha256sum(cachePath)
if err == nil && !strings.EqualFold(sum, spec.SHA256) {
// corrupted or tampered artifact: discard before extraction
} Try / catch
err := downloadRuntime(binDir, cachePath, spec)
if err != nil && strings.Contains(err.Error(), "sha256 mismatch") {
// delete cache, re-verify against the official published hash,
// update the manifest only if upstream legitimately re-signed
} Prevention
- Always pin sha256 in runtime.json (empty hash skips verification)
- Download runtimes only from the official, HTTPS-pinned URL
- Treat a mismatch as a security event first, a stale manifest second
When it happens
Trigger: A bit-flipped/truncated download that still passed the size check; the upstream asset was rebuilt without updating sha256 in runtime.json; a compromised or mis-mirrored CDN serving different content; an empty field would skip, so this only fires when a hash IS pinned.
Common situations: Re-published release assets; third-party mirrors injecting wrappers; flaky storage corrupting the cached file; hand-edited manifests.
Related errors
- size mismatch: got %d, expected %d (update runtime.json)
- download failed: %w
- download failed: HTTP %s
- download interrupted: %w
- unsafe path in archive: %s
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/8d550f2a411b7bf8.
Report an issue: GitHub.