go clean -modcache 是第一步,它删除 $GOMODCACHE 下所有已下载的 zip 包、解压源码和校验文件(如 .info、.ziphash),但保留 go.mod、go.sum 和 vendor 目录,清空后 go build 会按需自动重拉依赖。

直接执行 go clean -modcache,再运行 go mod download 或 go build 即可触发完整依赖重拉。这不是“重启环境”,而是精准清理模块缓存后按需重建——但必须确认 GO111MODULE=on,否则命令静默无效。
为什么 go clean -modcache 是第一步
它删的是 $GOMODCACHE(默认为 $GOPATH/pkg/mod)下所有已下载的 zip 包、解压源码和校验文件(如 .info、.ziphash)。这些是模块系统真正用来构建的底层数据,不是 go.mod 或 go.sum 本身。
常见误判:执行后 go build 报 cannot find module providing package xxx —— 这不是失败,是缓存清空后的正常等待;只要 go.mod 正确,下一步就会自动拉取。
- 不删
go.mod和go.sum,所以依赖声明完全保留 - 不碰
vendor/目录(如果存在),也不会影响你手动维护的 vendor 内容 - 若设了
GOPROXY=off,它会清$GOROOT/pkg/mod而非$GOPATH/pkg/mod,路径取决于当前代理配置
go mod download 和 go build 的行为差异
两者都会触发模块下载,但时机与范围不同:
-
go mod download严格按go.mod中require列表拉取,不编译,不检查 import 是否实际使用 -
go build ./...或go build .会先解析全部 import 路径,只拉取当前构建树真正需要的模块(含间接依赖),更贴近真实构建场景 - 如果项目用了
replace,两个命令都会尊重该指令;但若replace指向本地路径且该路径不存在,go build会直接报错,go mod download可能静默跳过
容易踩的坑:清理后仍拉不到最新版或 checksum mismatch
这不是缓存没清干净,而是模块来源或校验机制出了问题:
-
go env GOPRIVATE没设对:私有模块被默认代理拦截,导致拉到错误版本或校验失败 -
GOSUMDB仍是默认sum.golang.org,但你用了私有代理(如 Nexus),本地缓存校验数据与代理返回不一致 → 临时设GOSUMDB=off测试,确认后再配对 sumdb -
go list -m all显示的版本和go.mod不一致:大概率是旧.info文件残留,go clean -modcache后必须立刻跑go mod verify校验一致性 - CI 环境里反复执行
go clean -modcache:首次构建慢是必然的,但若每次都要重拉,说明没配GOPROXY或代理不可用
不想全清?只删某个模块更安全
全量清理简单,但团队协作中浪费带宽。精准删除某模块只需两步:
- 删解压源码:
rm -rf $(go env GOMODCACHE)/github.com/user/repo@v1.2.3 - 删原始 zip 和校验数据:
rm -rf $(go env GOMODCACHE)/cache/download/github.com/user/repo
注意:路径中的 @v1.2.3 必须和 go list -m all | grep repo 输出完全一致,包括 +incompatible 后缀;大小写和斜杠方向不能错。
真正麻烦的不是清理动作本身,而是清理后没人检查 go mod verify 是否通过,或者忽略 GOPRIVATE 配置是否匹配当前模块路径——这两点一旦出错,重拉的模块可能根本不对。

















