gohugoio/hugo · critical
verifying %s@%s: checksum mismatch: %s != %s
Error message
verifying %s@%s: checksum mismatch: %s != %s
What it means
Raised in writeHugoDirectSum when a direct module dependency resolved by a version query has a checksum that differs from the one recorded in Hugo's go.sum-style direct-sum file (hugo_direct.sum-like tracking). It is Hugo's own integrity check: the content of path@version changed since it was last recorded, which should never happen for immutable versions.
Source
Thrown at modules/client.go:636
sums = append(sums, modSum{pathVersionKey: pathVersionKey{path: m.Path(), version: m.Version()}, sum: m.Sum()})
}
}
// Read the existing sums.
existingSums, err := c.readModSumFile(hugoDirectSumFilename)
if err != nil {
return err
}
if len(sums) == 0 && len(existingSums) == 0 {
// Nothing to do.
return nil
}
dirty := len(sums) != len(existingSums)
for _, s1 := range sums {
if s2, ok := existingSums[s1.pathVersionKey]; ok {
if s1.sum != s2 {
return fmt.Errorf("verifying %s@%s: checksum mismatch: %s != %s", s1.path, s1.version, s1.sum, s2)
}
} else if !dirty {
dirty = true
}
}
if !dirty {
// Nothing changed.
return nil
}
// Write the sums file.
// First sort the sums for reproducible output.
sort.Slice(sums, func(i, j int) bool {
pvi, pvj := sums[i].pathVersionKey, sums[j].pathVersionKey
return pvi.path < pvj.path || (pvi.path == pvj.path && pvi.version < pvj.version)
})
f, err := c.fs.OpenFile(filepath.Join(c.ccfg.WorkingDir, hugoDirectSumFilename), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o666)View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Confirm upstream: check whether the module's tag was moved or re-published; if the change is legitimate, delete the stale entry (or the direct sum file) and rebuild to re-record it.
- Restore the sum file from version control if it was corrupted by a merge.
- If neither you nor upstream changed anything intentionally, treat it as possible tampering — pin an exact version and verify the repo contents before trusting it.
Defensive patterns
Strategy: validation
Validate before calling
// verify integrity before builds instead of discovering mismatch mid-run // shell: hugo mod verify // or programmatically compare go.sum entries against the module cache before Build
Try / catch
if err := client.Verify(clean); err != nil {
if strings.Contains(err.Error(), "checksum mismatch") {
// cache corruption or tampering — clean and re-download, never bypass
return fmt.Errorf("module cache integrity failure; run 'hugo mod clean' and re-download: %w", err)
}
return err
} Prevention
- Commit go.sum and never delete entries to silence mismatches
- On mismatch, clean the module cache and re-download; do NOT set GONOSUMCHECK/GOFLAGS=-mod=mod to bypass — a mismatch can indicate tampering
- Keep GOSUMDB enabled (sum.golang.org) so upstream tampering is caught at download time
- Run 'hugo mod verify' in CI before builds
When it happens
Trigger: Building a site whose module import uses a version query, where the freshly resolved module's Sum differs from the entry stored in the direct sum file in the working dir — e.g. an upstream tag was force-moved/retagged, or the sum file was edited or merged incorrectly.
Common situations: Theme authors deleting and re-pushing a tag, git merge conflicts resolved badly in the sum file, copying the sum file between projects, or a compromised/proxied module source serving different content.
Related errors
- failed to get %q: %w
- failed to init modules: %w
- failed to download module %s@%s: %s: %s
- failed to download module %s@%s: %w
- failed to decode module download result: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/4f11829b4ae7b0db.json.
Report an issue: GitHub ↗.