10aday › tools

Go pseudo-version generator and decoder

Need a commit that has no tag in your go.mod? Go wants a pseudo-version such as v1.6.1-0.20241114170450-2d3c2a9cc518, and a hand-made one is usually rejected. Give a module and a commit hash, branch or tag: the page asks the public Go module proxy, exactly like go get does, and gives you the lines to paste. Or paste a pseudo-version to see what it means and why Go refuses it.

1. Commit → pseudo-version

This button sends the module path and revision to proxy.golang.org (run by Google), as go get would. Nothing else leaves your browser. Private modules are not visible there.

2. Decode or check a pseudo-version

The 3 shapes of a pseudo-version

A pseudo-version is always base + commit time in UTC (14 digits) + first 12 characters of the commit hash. The base depends on the last tag before the commit, so that the pseudo-version sorts after that tag and before the next release.

Last tag before the commitPseudo-version (commit 2024-11-14 17:04:50 UTC, hash 2d3c2a9cc518…)Sorts

Computed in your browser by gpv.js, the same engine as the tool above. A +incompatible suffix is kept: it marks a v2+ tag in a repository without a /v2 module path.

What go says, and how to fix it

We asked the real go (1.26.0, 13 November 2026) for github.com/google/uuid at these versions. The right answer is v1.6.1-0.20241114170450-2d3c2a9cc518: the last tag is v1.6.0.

Version written in go.modWhat go saidFix
v1.6.1-0.20241114170450-2d3c2a9cc518✅ accepted—
v0.0.0-20241114170450-2d3c2a9cc518✅ accepted too: a v0.0.0 base never needs a tagFine, but it sorts below v1.6.0, so another module asking for v1.6.0 wins (Go keeps the highest).
v1.6.1-0.20241114170451-2d3c2a9cc518invalid pseudo-version: does not match version-control timestamp (expected 20241114170450)Use the time of the commit itself, in UTC, or let the tool above compute it.
v1.6.1-0.20241114170450-2d3c2a9cc5invalid pseudo-version: revision is shorter than canonical (expected 2d3c2a9cc518)Exactly 12 characters of the hash, lower case.
v1.6.2-0.20241114170450-2d3c2a9cc518invalid pseudo-version: preceding tag (v1.6.1) not foundThe base must be the last real tag + 1 on the patch number.
v1.6.0-0.20241114170450-2d3c2a9cc518invalid pseudo-version: version before v1.6.0 would have negative patch numberSame: v1.6.0 + 1 = v1.6.1-0.
v1.6.1-0.20241114170450-ffffffffffffinvalid version: unknown revision ffffffffffffThe commit is not in the public repository: push it, or check the hash.

When in doubt, write the bare hash (go get github.com/google/uuid@2d3c2a9, or the hash in place of the version in a replace line) and run go mod tidy: Go writes the correct pseudo-version itself.

Copy-paste lines

go get github.com/google/uuid@2d3c2a9
go list -m -json github.com/google/uuid@2d3c2a9     # prints Version and Time, changes nothing
GOPRIVATE=example.com/* go list -m -json example.com/private/repo@main   # private modules: ask git directly

Related: to check version ranges in npm, Cargo, Composer, pip and RubyGems, use the Version Constraint Checker; to sort versions as each package manager does, the Version sorter; for betas and RCs, what each package manager installs when a beta is out. For Java and .NET: Maven, Gradle and NuGet range checkers.

FAQ

How do I get the pseudo-version of a commit for go.mod?

Run go get module@commit or go list -m -json module@commit. The go command asks the module proxy, which returns the pseudo-version. The tool above sends the same request to proxy.golang.org, so you can copy the require or replace line.

What does v0.0.0-20191109021931-daa7c04131f5 mean?

v0.0.0: no tag comes before this commit. 20191109021931: the commit time in UTC, 2019-11-09 02:19:31. daa7c04131f5: the first 12 characters of the commit hash.

Why v1.6.1-0.… when the last tag is v1.6.0?

The pseudo-version must sort after its base tag and before the next release. Go adds 1 to the patch number and puts the date in a pre-release part, so v1.6.0 < v1.6.1-0.20241114170450-2d3c2a9cc518 < v1.6.1.

How do I fix “invalid pseudo-version: does not match version-control timestamp”?

The date in the version is not the commit time. Paste the version in part 2 above with its module: the page shows the corrected one. Or replace it with the bare hash and run go mod tidy. The error message itself gives the expected timestamp.

Can I write a pseudo-version by hand?

Since Go 1.13, go checks the base tag, the timestamp and the 12-character hash against the repository. A hand-made version is often rejected. Get it from go or from the proxy.

Does this work for private repositories?

The lookup does not: it uses the public proxy.golang.org. Run GOPRIVATE=example.com/* go list -m -json module@commit on your machine. The decoder works for any pseudo-version, offline.

Sources