Because Go tools authenticate a downloaded module against the first copy they saw. If the code behind a tag changes, the new download no longer matches and Go reports a security error. The fix is always the same: publish a new version rather than altering the old one.
What the Go documentation says
The Go page on publishing a module carries a plain note: do not change a tagged version of a module after publishing it. For developers using the module, Go tools authenticate a downloaded module against the first downloaded copy. If the two differ, the tools return a security error. Instead of changing the code for a previously published version, publish a new version.
The publishing steps on the same page are short: tidy the module's dependencies, run the tests a final time, tag the project with a new version number using git, push the tag, then run a list command so Go updates its index of modules.
What this protects
The design means a version number is a promise. Once your users, and the Go tooling around them, have seen v1.2.3, it should refer to the same bytes forever. That protects them from a tag being quietly repointed, by an attacker or by an honest maintainer who wanted to sneak in a late fix.
It also means a mistake in a published version is permanent in one sense: you cannot take it back by retagging.
What to do when you tagged the wrong thing
| Situation | Action |
|---|---|
| Tagged locally, not pushed | Delete or recreate the tag freely |
| Pushed but nobody could have used it | Still safer to use a new version number |
| Released with a bug | Fix and tag the next patch version |
| Released with a serious problem | Next version plus a retraction, see below |
Our post on what happens when a git tag moves after you pulled it explains the general problem that Go's design guards against.
Retraction as a signal
The Go modules reference describes a retract directive in go.mod. It indicates that a version or range of versions should not be depended upon, and is useful when a version was published prematurely or a severe problem was found after publication. Retracted versions remain available in version control and on module proxies so that builds depending on them do not break. Each directive should carry a comment explaining why, and the go command may show that comment in warnings and list output.
You publish a retraction by releasing a new version whose go.mod contains the directive. See what Go retract does for consumers for the other side of this.
// Published by mistake, contains a debug backdoor flag.
retract v1.2.3
A release routine that fits
- Tidy and test on the release commit.
- Tag with a semantic version and push the tag.
- Request the listing so the module index updates.
- If something is wrong, tag the next version. Add a retraction when the old one should not be used.
Quick check
Can I delete a bad Go tag to hide it?
Deleting the tag in your repository does not undo what proxies and users already fetched. Use a new version and, where fitting, a retraction.
Does a retraction remove the version?
No. The documentation says retracted versions remain available so builds are not broken. It is a warning, not a deletion.
Sources
Last reviewed: 19 October 2026.