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

  1. 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
  2. Delete the cached archive and re-download to rule out corruption in transit
  3. Download only from the official URL in the upstream repo; distrust mirrors after a mismatch
  4. 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

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


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/8d550f2a411b7bf8. Report an issue: GitHub.