golang/go · error
origin moved from %v %q to %v %q
Error message
origin moved from %v %q to %v %q
What it means
CheckReuse compares the old origin's VCS type and URL against the current repo. If either differs, the origin is considered to have moved and reuse is refused. The %v/%q pair shows old vs new VCS and URL.
Source
Thrown at src/cmd/go/internal/modfetch/codehost/vcs.go:385
// repoSumOrigin returns an Origin containing a RepoSum.
func (r *vcsRepo) repoSumOrigin(ctx context.Context) *Origin {
origin := &Origin{
VCS: r.cmd.vcs,
URL: r.remote,
RepoSum: r.repoSum,
}
r.repoSumOnce.Do(func() { r.loadRepoSum(ctx) })
origin.RepoSum = r.repoSum
return origin
}
func (r *vcsRepo) CheckReuse(ctx context.Context, old *Origin, subdir string) error {
if old == nil {
return fmt.Errorf("missing origin")
}
if old.VCS != r.cmd.vcs || old.URL != r.remote {
return fmt.Errorf("origin moved from %v %q to %v %q", old.VCS, old.URL, r.cmd.vcs, r.remote)
}
if old.Subdir != subdir {
return fmt.Errorf("origin moved from %v %q %q to %v %q %q", old.VCS, old.URL, old.Subdir, r.cmd.vcs, r.remote, subdir)
}
if old.Ref == "" && old.RepoSum == "" && old.Hash != "" {
// Hash has to remain in repo.
hash, err := r.lookupRef(ctx, old.Hash)
if err == nil && hash == old.Hash {
return nil
}
if err != nil {
return fmt.Errorf("looking up hash: %v", err)
}
return fmt.Errorf("hash changed") // weird but maybe they made a tag
}
if old.Ref != "" && old.RepoSum == "" {View on GitHub (pinned to b6b368adc5)
Solutions
- Run `go clean -modcache` (or remove the specific module directory) so the stale origin is discarded and re-fetched from the new remote.
- Align the replace directive with the new upstream URL.
- Update the vanity server's go-import meta tag consistently so all clients see the same VCS+URL.
Example fix
// before — cache says hg https://old.example.org/m, meta tag now points to https://new.example.org/m $ go build // error: origin moved from hg "https://old.example.org/m" to hg "https://new.example.org/m" // after $ go clean -modcache && go build
Defensive patterns
Strategy: fallback
Validate before calling
func originMatches(old *codehost.Origin, vcs, url string) bool {
return old != nil && old.VCS == vcs && old.URL == url
} Try / catch
if err := repo.CheckReuse(ctx, old, subdir); err != nil {
if strings.HasPrefix(err.Error(), "origin moved") {
// upstream moved — invalidate cache and re-download
go cleanModCache(modulePath)
}
} Prevention
- When migrating upstream hosts, increment a vanity path version or announce the move so caches can be flushed.
- Keep replace directives aligned with the live upstream URL.
When it happens
Trigger: A cached Origin records VCS=hg URL=A, but the current repo is VCS=hg URL=B (or the VCS type itself changed). Typical when a vanity server redirected the import path to a different backing repo.
Common situations: Upstream project migrated hosts (e.g. Bitbucket to GitHub) and updated the go-import meta tag; a vanity server rotated its canonical URL; a replace directive points to a different remote than the cached origin.
Related errors
- origin moved from %v %q %q to %v %q %q
- leading slash
- no scheme
- file scheme disallowed
- unknown vcs: %s %s
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/880869e7a26b6adc.
Report an issue: GitHub.