{"id":"4f11829b4ae7b0db","repo":"gohugoio/hugo","slug":"verifying-s-s-checksum-mismatch-s-s","errorCode":null,"errorMessage":"verifying %s@%s: checksum mismatch: %s != %s","messagePattern":"verifying (.+?)@(.+?): checksum mismatch: (.+?) != (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"modules/client.go","lineNumber":636,"sourceCode":"\t\t\tsums = append(sums, modSum{pathVersionKey: pathVersionKey{path: m.Path(), version: m.Version()}, sum: m.Sum()})\n\t\t}\n\t}\n\n\t// Read the existing sums.\n\texistingSums, err := c.readModSumFile(hugoDirectSumFilename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(sums) == 0 && len(existingSums) == 0 {\n\t\t// Nothing to do.\n\t\treturn nil\n\t}\n\n\tdirty := len(sums) != len(existingSums)\n\tfor _, s1 := range sums {\n\t\tif s2, ok := existingSums[s1.pathVersionKey]; ok {\n\t\t\tif s1.sum != s2 {\n\t\t\t\treturn fmt.Errorf(\"verifying %s@%s: checksum mismatch: %s != %s\", s1.path, s1.version, s1.sum, s2)\n\t\t\t}\n\t\t} else if !dirty {\n\t\t\tdirty = true\n\t\t}\n\t}\n\tif !dirty {\n\t\t// Nothing changed.\n\t\treturn nil\n\t}\n\n\t// Write the sums file.\n\t// First sort the sums for reproducible output.\n\tsort.Slice(sums, func(i, j int) bool {\n\t\tpvi, pvj := sums[i].pathVersionKey, sums[j].pathVersionKey\n\t\treturn pvi.path < pvj.path || (pvi.path == pvj.path && pvi.version < pvj.version)\n\t})\n\n\tf, err := c.fs.OpenFile(filepath.Join(c.ccfg.WorkingDir, hugoDirectSumFilename), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o666)","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/modules/client.go#L618-L654","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify integrity before builds instead of discovering mismatch mid-run\n// shell: hugo mod verify\n// or programmatically compare go.sum entries against the module cache before Build","typeGuard":null,"tryCatchPattern":"if err := client.Verify(clean); err != nil {\n    if strings.Contains(err.Error(), \"checksum mismatch\") {\n        // cache corruption or tampering — clean and re-download, never bypass\n        return fmt.Errorf(\"module cache integrity failure; run 'hugo mod clean' and re-download: %w\", err)\n    }\n    return err\n}","preventionTips":["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"],"tags":["go-modules","hugo-mod","checksum","security","integrity"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}