What is GOPROXY, and how does the module proxy and checksum database work?

5 minadvancedgomodulesgoproxygosumdb

Quick Answer

GOPROXY tells the go command where to fetch module source code from, instead of hitting version control hosts (like GitHub) directly on every build — the default, https://proxy.golang.org, is a public, Google-operated proxy that caches modules indefinitely, making builds faster and more resilient to a source repository being deleted, moved, or temporarily down. Alongside it, GOSUMDB (default sum.golang.org) is a separate, append-only, cryptographically verifiable log of module checksums, checked against your local go.sum to detect if a module version's content has ever changed after being published, which would indicate tampering or an unexpected mutation. Together they mean go build gets modules from a fast, cached source and cryptographically verifies they're exactly the bytes that were originally published, without needing to trust the proxy operator blindly.

Detailed Answer

The module proxy and checksum database work together to make go get/go build both fast and verifiably tamper-resistant.

The default proxy chain

go env GOPROXY
# https://proxy.golang.org,direct

go tries proxy.golang.org first; direct as a fallback means "go fetch it straight from the module's version control host" if the proxy doesn't have it (or if GOPROXY is explicitly set to direct).

Why a proxy at all

Without a proxy:
  go get github.com/some/pkg@v1.2.3
    -> clones directly from GitHub every time, for every developer, every CI run
    -> breaks if the repo is deleted, renamed, made private, or GitHub is down

With the proxy:
  go get github.com/some/pkg@v1.2.3
    -> fetches from proxy.golang.org's immutable cache
    -> works even if the original repo later disappears

Once a module version is fetched through the proxy, it's cached there permanently (module versions are meant to be immutable), which protects against the surprisingly common "left-pad" style problem of a dependency vanishing.

Verifying with GOSUMDB

go env GOSUMDB
# sum.golang.org
go.sum:
github.com/some/pkg v1.2.3 h1:AbCdEf...=

When you first fetch a module version, go checks its hash against sum.golang.org's append-only transparency log and records it in your go.sum. On every subsequent build, go re-verifies the locally cached module against that recorded hash. If the module's content ever silently changed — a compromised registry, a maintainer force-pushing over a tag — the build fails loudly instead of silently using different code.

Disabling for private or restricted environments

GOPRIVATE=github.com/mycompany/* go build ./...
GONOSUMCHECK=1   # older, mostly superseded by GOPRIVATE/GONOSUMDB
GOFLAGS=-mod=mod

GOPRIVATE (covered in a later question) tells go to skip both the proxy and the checksum database for matching module paths, which is essential for internal, non-public modules that a public proxy would never be able to reach anyway.

Related Resources