golang/go · info
tags changed
Error message
tags changed
What it means
Thrown by gitRepo.CheckReuse when old.TagSum is set and the current tag set checksum (computed over tags matching old.TagPrefix) differs from the recorded value. This means tags were added, removed, or changed in the relevant prefix since the cache entry was written.
Source
Thrown at src/cmd/go/internal/modfetch/codehost/git.go:236
return r.refsErr
}
if old.Ref != "" {
hash, ok := r.refs[old.Ref]
if !ok {
return fmt.Errorf("ref %q deleted", old.Ref)
}
if hash != old.Hash {
return fmt.Errorf("ref %q moved from %s to %s", old.Ref, old.Hash, hash)
}
}
if old.TagSum != "" {
tags, err := r.Tags(ctx, old.TagPrefix)
if err != nil {
return err
}
if tags.Origin.TagSum != old.TagSum {
return fmt.Errorf("tags changed")
}
}
if old.RepoSum != "" {
if r.repoSum(r.refs) != old.RepoSum {
return fmt.Errorf("refs changed")
}
}
return nil
}
// loadRefs loads heads and tags references from the remote into the map r.refs.
// The result is cached in memory.
func (r *gitRepo) loadRefs(ctx context.Context) (map[string]string, error) {
if r.local { // Return results from the cache if local only.
// In the future, we could consider loading r.refs using local git commands
// if desired.
return nil, nil
}View on GitHub (pinned to b6b368adc5)
Solutions
- This is usually benign — just re-fetch: 'go mod download' or 'go get module@latest'.
- If you want stability, pin to a specific version: 'go get module@v1.2.3'.
- Run 'go mod tidy' to update go.sum entries.
- If using GOPROXY=off, switch to a proxy or direct to allow re-fetch.
Example fix
# before: cache has stale tag set go build ./... # fails with 'tags changed' # after: re-fetch GONOSUMCHECK=1 go mod download go build ./...
Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
null
Try / catch
// 'tags changed' is expected when upstream releases new versions; re-fetch
err := repo.CheckReuse(ctx, old, subdir)
if err != nil && strings.Contains(err.Error(), "tags changed") {
// force re-fetch
info, ferr := repo.Stat(ctx, rev)
if ferr == nil { return useInfo(info) }
return ferr
} Prevention
- Treat 'tags changed' / 'refs changed' as soft cache invalidation, not hard errors.
- Pin to exact versions to make these checks deterministic.
- Keep the cache fresh with periodic 'go mod download'.
When it happens
Trigger: CheckReuse where the upstream repo's tags (under the recorded prefix) have changed — new version tags published, old tags removed. The TagSum is a checksum over the tag set, so any change triggers this.
Common situations: A new version of the module was tagged upstream since your last fetch; tags were reorganized; depending on a module via 'latest' or a pseudo-version that depends on tag availability. This is expected behavior when a module releases a new version.
Related errors
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/360b800daf6db277.
Report an issue: GitHub.