应使用 replace 指向可信 fork 仓库并确保含完整 go.mod,配合 go mod tidy;仅当临时调试且无法获取 fork 时才慎用 gosumdb=off,因 goproxy 无法解决源删除导致的 404。

go get 报错 module github.com/xxx/yyy: reading github.com/xxx/yyy/@v/v1.2.3.mod: 404 Not Found 怎么办
源头仓库被删,go get 就会卡在 fetch .mod 文件这一步——Go 默认只从原始路径拉取,不自动 fallback。这不是网络问题,是模块元数据彻底失效。
- 先确认是否真被删:用浏览器或
curl -I https://github.com/xxx/yyy/@v/v1.2.3.mod看返回是不是 404 - 别急着换代理或重试,换源也无效,因为 Go 模块校验依赖的是原始
sum.golang.org记录,而它只存哈希,不存代码 - 真正能绕过的方式是让 Go **跳过校验并指定新位置**,靠
replace+downloaded module cache配合实现
用 replace 指向 fork 后的镜像仓库
最稳妥的做法是找一个可信 fork(比如公司内网 GitLab、或社区维护的归档仓库),然后在 go.mod 里硬绑定。Go 构建时会优先使用 replace 路径,完全绕过原地址。
- 确保 fork 的 commit hash 和原模块 v1.2.3 tag 一致(用
git log -n 1 v1.2.3对比) - 在
go.mod末尾加一行:replace github.com/xxx/yyy => gitlab.example.com/mirror/yyy v1.2.3 - 执行
go mod tidy,此时 Go 会从新地址下载,并把 checksum 写进go.sum(注意:会覆盖原记录,后续构建不再校验原始源) - 如果 fork 地址需要认证(如 SSH 或 token),确保
~/.netrc或git config已配置好凭据
临时禁用校验只用于调试(慎用)
仅限本地验证逻辑、无法获取 fork 的极端情况。生产环境绝对不要用,会破坏模块完整性保障。
- 设环境变量:
GOSUMDB=off,再跑go build或go mod download - 或者用
go env -w GOSUMDB=off永久关闭(不推荐) - 关闭后 Go 不再查
sum.golang.org,但依然会尝试 fetch 原始.mod和.zip—— 所以必须配合replace,否则还是 404 - 关掉
GOSUMDB后,go.sum里对应条目会变成h1:开头的空哈希,CI 流水线通常会拒绝这种状态
为什么不能只改 GOPROXY?
GOPROXY 只控制「下载代理」,不是「源映射」。即使设成 https://goproxy.cn 或自建 proxy,它内部仍要回源抓取原始 @v/v1.2.3.mod —— 源没了,proxy 也吐不出东西。
- proxy 缓存是按原始 module path 存的,不会自动 rehost 到新路径
- 有些 proxy 支持
fallback配置(如 Athens),但需手动配置 rewrite rule,且要求你有权限改 proxy 服务端 - 真正起效的只有客户端层面的
replace,它是 Go toolchain 唯一允许「重写导入路径」的机制
最容易被忽略的是:replace 的目标仓库必须包含完整的 go.mod 文件(不能只是代码快照),否则 go mod download 会失败。很多 fork 只 clone 了 src,忘了打 tag 或提交 go.mod。











