golang/go · warning

hash changed

Error message

hash changed

What it means

Hash verification branch: lookupRef succeeded but returned a different hash than old.Hash. The inline comment says 'weird but maybe they made a tag' — this means the ref now resolves to a different commit, indicating the tag/branch was reassigned or the repo was rewritten.

Source

Thrown at src/cmd/go/internal/modfetch/codehost/vcs.go:400

		return fmt.Errorf("missing origin")
	}
	if old.VCS != r.cmd.vcs || old.URL != r.remote {
		return fmt.Errorf("origin moved from %v %q to %v %q", old.VCS, old.URL, r.cmd.vcs, r.remote)
	}
	if old.Subdir != subdir {
		return fmt.Errorf("origin moved from %v %q %q to %v %q %q", old.VCS, old.URL, old.Subdir, r.cmd.vcs, r.remote, subdir)
	}

	if old.Ref == "" && old.RepoSum == "" && old.Hash != "" {
		// Hash has to remain in repo.
		hash, err := r.lookupRef(ctx, old.Hash)
		if err == nil && hash == old.Hash {
			return nil
		}
		if err != nil {
			return fmt.Errorf("looking up hash: %v", err)
		}
		return fmt.Errorf("hash changed") // weird but maybe they made a tag
	}

	if old.Ref != "" && old.RepoSum == "" {
		hash, err := r.lookupRef(ctx, old.Ref)
		if err == nil && hash != "" && hash == old.Hash {
			return nil
		}
	}

	r.repoSumOnce.Do(func() { r.loadRepoSum(ctx) })
	if r.repoSum != "" {
		if old.RepoSum == "" {
			return fmt.Errorf("non-specific origin")
		}
		if old.RepoSum != r.repoSum {
			return fmt.Errorf("repo changed")
		}
		return nil

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Pin to an explicit semver tag in go.mod instead of a branch or commit that can move.
  2. Run `go clean -modcache` and re-resolve — the new hash becomes the baseline.
  3. If you control the upstream, avoid retagging; if a yank is needed, use module retraction instead.
  4. Audit go.sum for the affected module and update checksums after confirming the new commit is legitimate.
Defensive patterns

Strategy: validation

Validate before calling

func hashStable(oldHash, resolvedHash string) bool {
    return oldHash == resolvedHash
}

Prevention

When it happens

Trigger: old.Hash recorded a specific commit, lookupRef(old.Hash) returns a non-matching hash — upstream force-pushed, retagged, or rewrote history at that name.

Common situations: Upstream retagged a release to a different commit (rare but happens after yanks); a branch used as a ref was reset; repository was rewritten with git filter-branch.

Related errors


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