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

  1. This is usually benign — just re-fetch: 'go mod download' or 'go get module@latest'.
  2. If you want stability, pin to a specific version: 'go get module@v1.2.3'.
  3. Run 'go mod tidy' to update go.sum entries.
  4. 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

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.