golang/go · error
does not match version-control timestamp (expected %s)
Error message
does not match version-control timestamp (expected %s)
What it means
validatePseudoVersion (coderepo.go:705-711) parses the UTC timestamp encoded in the pseudo-version and compares it (to the second) against info.Time from the VCS. A mismatch means the timestamp in the version string lies about when the commit was made. The timestamp is load-bearing for version ordering, so a wrong timestamp would let authors artificially inflate precedence — hence the strict check.
Source
Thrown at src/cmd/go/internal/modfetch/coderepo.go:710
return err
}
if rev != info.Short {
switch {
case strings.HasPrefix(rev, info.Short):
return fmt.Errorf("revision is longer than canonical (expected %s)", info.Short)
case strings.HasPrefix(info.Short, rev):
return fmt.Errorf("revision is shorter than canonical (expected %s)", info.Short)
default:
return fmt.Errorf("does not match short name of revision (expected %s)", info.Short)
}
}
t, err := module.PseudoVersionTime(version)
if err != nil {
return err
}
if !t.Equal(info.Time.Truncate(time.Second)) {
return fmt.Errorf("does not match version-control timestamp (expected %s)", info.Time.UTC().Format(module.PseudoVersionTimestampFormat))
}
tagPrefix := ""
if r.codeDir != "" {
tagPrefix = r.codeDir + "/"
}
// A pseudo-version should have a precedence just above its parent revisions,
// and no higher. Otherwise, it would be possible for library authors to "pin"
// dependency versions (and bypass the usual minimum version selection) by
// naming an extremely high pseudo-version rather than an accurate one.
//
// Moreover, if we allow a pseudo-version to use any arbitrary pre-release
// tag, we end up with infinitely many possible names for each commit. Each
// name consumes resources in the module cache and proxies, so we want to
// restrict them to a finite set under control of the module author.
//
// We address both of these issues by requiring the tag upon which theView on GitHub (pinned to b6b368adc5)
Solutions
- Let the toolchain derive the pseudo-version: `go get <module>@<commit>` — it reads the commit time from the VCS and formats it correctly.
- If constructing manually, use `git log -1 --format=%cI <commit>` to get the UTC timestamp and the format `YYYYMMDDHHMMSS`.
- After upstream rebases that alter commit times, refresh affected pseudo-versions.
Example fix
// before (timestamp does not match commit) require example.com/m v0.0.0-20231231235959-e3702bed3d42 // after (use the commit's actual UTC time) require example.com/m v0.0.0-20240101120000-e3702bed3d42
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the timestamp matches the commit's UTC time.
// bash:
// ts=$(git log -1 --format=%cI <commit> | date -u +%Y%m%d%H%M%S)
// # the pseudo-version must contain this exact timestamp
//
// Go:
package main
import ("time"; "golang.org/x/mod/module")
func validateTs(pseudo string, commitTime time.Time) error {
t, err := module.PseudoVersionTime(pseudo)
if err != nil { return err }
if !t.Equal(commitTime.Truncate(time.Second)) {
return fmt.Errorf("timestamp mismatch: pseudo=%s commit=%s", t, commitTime)
}
return nil
} Prevention
- Always derive pseudo-versions through the toolchain, never by hand.
- Use `%cI` (strict ISO 8601) and convert to UTC before formatting.
- After rebases that change commit times, refresh pseudo-versions.
When it happens
Trigger: Hand-building a pseudo-version with an invented or rounded timestamp; timezone mishandling when constructing the UTC timestamp; a VCS reports commit time in a non-UTC zone and the constructor didn't convert.
Common situations: Generating pseudo-versions with `date -u` but wrong format string; rebases that change commit timestamps; pseudo-versions built before the toolchain enforced the canonical timestamp format.
Related errors
- revision is longer than canonical (expected %s)
- revision is shorter than canonical (expected %s)
- preceding tag (%s) not found
- not a descendent of preceding tag (%s)
- resolves to version %v (%s is not a tag)
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/2d3ca9aeb45e043a.
Report an issue: GitHub.