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

  1. 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.
  2. Restore the sum file from version control if it was corrupted by a merge.
  3. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/4f11829b4ae7b0db.json. Report an issue: GitHub ↗.