Quick answer
Run this from your module root, then commit both files it changes:
go mod tidy
git add go.mod go.sum
That's the whole fix for the vast majority of cases. Keep reading if it's happening only in CI, or if go mod tidy itself fails.
The exact error string
$ go build ./...
missing go.sum entry for module providing package github.com/pkg/errors (imported by example.com/myapp); to add:
go mod download github.com/pkg/errors
// a related, shorter-form wording you'll also see (from "go mod download"
// itself, or a slightly different Go version) points at the same fix:
github.com/pkg/errors@v0.9.1: missing go.sum entry; to add it:
go mod download github.com/pkg/errors
Both wordings mean the same thing: go.mod requires this module, but go.sum has no verification hash for the exact version being used, and Go's default read-only mode refuses to fetch and write one automatically. The message even suggests the fix — go mod download <module> works, but go mod tidy (below) is more complete and just as fast.
Why this happens
Since Go 1.16, the module system defaults to -mod=readonly: a build will not silently rewrite go.mod or go.sum on your behalf. Before that default, an ordinary go build would fetch whatever was missing and fix the files for you, which is convenient locally but means a broken or incomplete go.sum can slip past your own machine unnoticed — and then surface for the next person, or in CI, as a hard failure instead of the silent auto-fix you got used to.
The usual triggers, in rough order of frequency:
- You edited an import by hand (added a new package, or your editor auto-imported one) and never ran
go getorgo mod tidyafterward. go.sumwasn't committed to version control at all — see the FAQ below, this is a real and common mistake.- A merge produced a conflict in
go.sumthat was resolved incorrectly, leaving it internally inconsistent. - You're building on a machine or CI runner with an empty module cache and restricted network access, so nothing can be fetched to fill the gap on the fly.
Fix 1 (fastest): go mod tidy
This is the dominant fix and should be your first move. It reconciles go.mod and go.sum against what your code actually imports in one pass — adding anything missing, removing anything unused:
$ go mod tidy
go: downloading github.com/pkg/errors v0.9.1
$ go build ./...
$ echo $?
0
go build printing nothing at all, with a 0 exit status, is the expected success signal — Go's tools are silent when there's nothing to report. Commit the result:
git add go.mod go.sum
git commit -m "go mod tidy"
Fix 2: go mod download (when you don't want go.mod to change)
If you specifically don't want go mod tidy touching your requirement list — for instance you're mid-investigation and don't want unrelated tidy-ups in the same commit — download just the missing module's hash:
go mod download github.com/pkg/errors
This only works if the module is already correctly listed in go.mod; if the import is missing from go.mod entirely (you added the import but never ran go get), you'll need go get or go mod tidy instead, since go mod download doesn't add new requirements.
Fix 3: it's a private module (GOPRIVATE)
If the package lives in a private repository, the public checksum database (sum.golang.org) can't verify it — and shouldn't be asked to, since that would leak your private module's path to a third party. Tell the Go tool to skip both the public proxy and the sum database for it:
go env -w GOPRIVATE=github.com/yourorg/*
go mod tidy
GOPRIVATE covers both proxy bypass and sum-database bypass for matching module paths in one setting; the narrower GONOSUMCHECK/GOSUMDB=off knobs exist too but are blunter (they affect everything, not just your private paths) and are usually the wrong tool for this specific problem.
Fix 4: it only fails in CI
If go build works locally but fails with this error in CI specifically, the difference is almost always cache and network, not your code:
- Your local module cache (
$GOPATH/pkg/mod) may already contain the package from a previousgo get, quietly papering over an incompletego.sum. CI usually starts from a clean cache, so it's the one that catches the real problem. - CI runners are frequently network-restricted for module downloads (allow-listed proxies, or none at all), so
go mod downloadcan't fetch what's missing even if it wanted to. The fix has to happen before CI runs — commit a completego.sum, don't rely on CI to generate it. - Confirm CI is checking out
go.sumat all: a.gitignorethat excludes it (see below) means every CI run starts from an incomplete file no matter what you commit locally.
go.mod vs go.sum
| go.mod | go.sum | |
|---|---|---|
| Declares | Which module versions are required | A hash verifying each required module's content |
| Changed by | go get, go mod tidy, manual edits | go mod tidy, go mod download (never by hand) |
| Commit to git? | Always | Always — it is not a disposable lockfile |
| Missing entry means | Build fails immediately, clear message | This error — version known, hash unverifiable |
Debugging checklist
- ✓ Run
go mod tidyfrom the module root first — it fixes the large majority of cases - ✓ Confirm
go.sumis tracked by git, not in.gitignore - ✓ Commit both
go.modandgo.sumtogether, every time either changes - ✓ Only failing in CI? Check network access to the module proxy and confirm
go.sumis actually checked out there - ✓ Private module? Set
GOPRIVATErather than disabling checksum verification globally - ✓ Recent merge? Check
go.sumwasn't left in a conflicted or partially-resolved state - ✓ Still stuck? Delete
go.sumand regenerate it fresh withgo mod tidy(safe — it's fully derived fromgo.modplus the actual module content)
Frequently Asked Questions
How do I fix 'missing go.sum entry for module providing package X'?
Run go mod tidy from your module root, then commit the updated go.mod and go.sum. It resolves every import in your code against your dependencies, adds any missing go.sum hashes, and removes ones you no longer need, in one pass.
What is go.sum for, and how is it different from go.mod?
go.mod declares which module versions your project requires. go.sum records a cryptographic hash of each required module's content, so that if the same version is ever downloaded again — by you, a teammate, or CI — the build can verify it byte-for-byte matches what you originally used. go.mod says what version; go.sum proves it hasn't changed.
Why does this only fail in CI and not on my machine?
Your local module cache may already hold the package from an earlier go get, so the build succeeds even with a stale go.sum. Go 1.16 made -mod=readonly the default, which refuses to write go.sum automatically during a build — CI runners typically start with an empty cache and no network access for module downloads, so a genuinely incomplete go.sum fails there even though it happened to work locally.
Should go.sum be committed to version control?
Yes — always commit go.sum alongside go.mod. Unlike some ecosystems' lockfiles, go.sum isn't a local cache artifact; it's the supply-chain integrity record every teammate and CI run needs. Gitignoring it is a common and serious mistake that causes exactly this error for everyone except the person who originally ran go get.
Is 'go mod download' enough, or do I need 'go mod tidy'?
go mod download only adds hashes for modules already listed in go.mod — use it when you don't want go.mod itself to change. go mod tidy is the more complete fix: it also adds any requirement missing from go.mod entirely (for example after adding a new import without running go get) and removes unused ones. When in doubt, use go mod tidy.
More Go & backend errors
Browse the full reference for Go, Rust, and Java errors — exact message, cause, and fix.