golang/go · error · module.VersionError

verifying %s: %v

Error message

verifying %s: %v

What it means

checkSumDB calls lookupSumDB to fetch checksum lines from the configured Go checksum database (sum.golang.org by default). If lookupSumDB returns an error — DNS failure, TLS problem, HTTP 5xx, GONOSUMDB/SUMDB misconfiguration, or GONOSUMCHECK disabled — it is wrapped as 'verifying {module|go.mod}:'.

Source

Thrown at src/cmd/go/internal/modfetch/fetch.go:860

	if len(f.sumState.m[mod]) > 0 {
		fmt.Fprintf(os.Stderr, "warning: verifying %s@%s: unknown hashes in go.sum: %v; adding %v"+hashVersionMismatch, mod.Path, mod.Version, strings.Join(f.sumState.m[mod], ", "), h)
	}
	f.sumState.m[mod] = append(f.sumState.m[mod], h)
}

// checkSumDB checks the mod, h pair against the Go checksum database.
// It calls base.Fatalf if the hash is to be rejected.
func checkSumDB(mod module.Version, h string) error {
	modWithoutSuffix := mod
	noun := "module"
	if before, found := strings.CutSuffix(mod.Version, "/go.mod"); found {
		noun = "go.mod"
		modWithoutSuffix.Version = before
	}

	db, lines, err := lookupSumDB(mod)
	if err != nil {
		return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: %v", noun, err))
	}

	have := mod.Path + " " + mod.Version + " " + h
	prefix := mod.Path + " " + mod.Version + " h1:"
	for _, line := range lines {
		if line == have {
			return nil
		}
		if strings.HasPrefix(line, prefix) {
			return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, noun, h, db, line[len(prefix)-len("h1:"):]))
		}
	}
	return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum missing from sumdb response"+sumdbAbsent, noun))
}

// Sum returns the checksum for the downloaded copy of the given module,
// if present in the download cache.
func Sum(ctx context.Context, mod module.Version) string {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Verify connectivity to the configured SUMDB host (curl https://sum.golang.org) and check corporate proxy/TLS settings.
  2. For private modules set GOPRIVATE/GONOSUMDB so they bypass the public sumdb.
  3. Point GONOSUMDB at an internal mirror if you run one, or set GONOSUMCHECK appropriately for the environment.
  4. Retry — sumdb outages are usually short.
Defensive patterns

Strategy: retry

Validate before calling

// Confirm sumdb reachability before running go commands that verify.
func sumdbReachable(ctx context.Context, db string) error {
    if db == "" { db = "sum.golang.org" }
    var d net.Dialer
    c, err := d.DialContext(ctx, "tcp", db+":443")
    if err != nil { return err }
    c.Close()
    return nil
}

Try / catch

// Retry sumdb lookups with backoff, then surface a clear network error.
var lastErr error
for i := 0; i < 3; i++ {
    if err := modfetch.CheckSumDB(mod, h); err == nil { return nil } else { lastErr = err }
    time.Sleep(time.Duration(1<<i) * time.Second)
}
return lastErr

Prevention

When it happens

Trigger: lookupSumDB returns err != nil before any lines are inspected. The wrap attaches noun (module or go.mod) and the proxy/db identifier.

Common situations: Air-gapped network blocking sum.golang.org; corporate MITM proxy that breaks TLS; SUMDB pointed at a private mirror that is down; GONOSUMDB set without a working private DB; transient outage of sum.golang.org.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/1d2032f7fa567969. Report an issue: GitHub.