golang/go · critical

SHA-256 hash of %s is %s, want %s (from %s)

Error message

SHA-256 hash of %s is %s, want %s (from %s)

What it means

Returned by verifyZipSum when the FIPS 140 snapshot zip's actual SHA-256 hash does not equal the hash recorded for its basename in GOROOT/lib/fips140/fips140.sum. The mismatch indicates corruption, a partial download, or tampering — verification intentionally refuses to proceed.

Source

Thrown at src/cmd/go/internal/fips140/fips140.go:286

		if n == name {
			want = strings.TrimSpace(h)
			break
		}
	}
	if want == "" {
		return fmt.Errorf("no SHA-256 hash for %s in %s", name, sumfile)
	}
	f, err := os.Open(zipfile)
	if err != nil {
		return err
	}
	defer f.Close()
	h := sha256.New()
	if _, err := io.Copy(h, f); err != nil {
		return err
	}
	if got := fmt.Sprintf("%x", h.Sum(nil)); got != want {
		return fmt.Errorf("SHA-256 hash of %s is %s, want %s (from %s)", name, got, want, sumfile)
	}
	return nil
}

// ResolveImport resolves the import path imp.
// If it is of the form crypto/internal/fips140/foo
// (not crypto/internal/fips140/v1.2.3/foo)
// and we are using a snapshot, then LookupImport
// rewrites the path to crypto/internal/fips140/v1.2.3/foo
// and returns that path and its location in the unpacked
// FIPS snapshot.
func ResolveImport(imp string) (newPath, dir string, ok bool) {
	checkInit()
	const fips = "crypto/internal/fips140"
	if !Snapshot() || !str.HasPathPrefix(imp, fips) {
		return "", "", false
	}
	fipsv := path.Join(fips, version)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Clean the module cache entry for the FIPS snapshot (`go clean -modcache` for the affected module) and let the go command re-fetch/re-unpack.
  2. Reinstall/upgrade the Go toolchain to restore a pristine GOROOT/lib/fips140/fips140.sum and bundled snapshots.
  3. If the sum file was edited, restore it from the toolchain distribution.
  4. Verify disk health if corruption recurs — intermittent bit-rot produces the same symptom.

Example fix

# before — corrupted cache zip
$ GOFIPS140=v1.2.3 go build ./...
error: SHA-256 hash of fips140-v1.2.3.zip is <got>, want <want>
# after — purge and rebuild
$ go clean -modcache && GOFIPS140=v1.2.3 go build ./...
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-verify the snapshot zip's SHA-256 against the recorded hash to give
// a clear, actionable message before the go command fails.
func preVerify(zipfile, sumfile string) error {
    want, err := recordedHash(sumfile, filepath.Base(zipfile))
    if err != nil { return err }
    f, err := os.Open(zipfile)
    if err != nil { return err }
    defer f.Close()
    h := sha256.New()
    if _, err := io.Copy(h, f); err != nil { return err }
    if fmt.Sprintf("%x", h.Sum(nil)) != want {
        return fmt.Errorf("snapshot %s corrupted — run `go clean -modcache`", zipfile)
    }
    return nil
}

Try / catch

// Treat integrity failures as recoverable by clearing the cache and retrying once.
err = runBuild()
if isHashMismatch(err) {
    _ = runGo("clean", "-modcache")
    err = runBuild()
}
if err != nil { return err }

Prevention

When it happens

Trigger: Any of: the zip in the module cache is truncated/corrupted; the zip was replaced with a different file; the fips140.sum file was edited and now disagrees with the zip; a partially-written download.

Common situations: Interrupted downloads leaving a truncated zip; cache corruption on disk; manual edits to fips140.sum; copying zips between machines with different snapshots.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/6ebe350106be2893. Report an issue: GitHub.