go clean -modcache 会无差别清空整个 $gomodcache,删除所有模块源码、.zip 包和校验文件,导致重复下载和构建失败;安全做法是仅清理未被当前项目使用的模块,结合 go list -m all、路径比对与精准删除,并注意 gosumdb/goproxy 切换后的残留校验数据。

go clean -modcache 会清空整个 $GOMODCACHE,不是“安全清理”
直接执行 go clean -modcache 会删除 $GOPATH/pkg/mod(或 $GOROOT/pkg/mod)下所有模块源码、.zip 包和校验文件,包括当前项目依赖的、其他项目也在用的模块。它不区分“谁在用”,只管“全删”。项目下次构建时必须重下全部依赖,CI 超时、本地构建卡住、私有模块拉取失败都可能发生。
真正安全的做法:只删不用的模块,保留共用缓存
目标是释放空间 + 避免污染,又不打断其他项目。关键不是“删多少”,而是“删哪些”:
- 先导出当前项目实际依赖树:
go list -m all > deps.txt - 提取所有模块路径(去重):
awk '{print $1}' deps.txt | sort -u > used_modules.txt - 对比
$GOMODCACHE下真实存在的模块目录:ls -d $GOMODCACHE/*/*@* 2>/dev/null | xargs -n1 basename | cut -d@ -f1 - 手动删掉不在
used_modules.txt中的模块目录(注意保留@v版本后缀):rm -rf $GOMODCACHE/github.com/old-project@v0.1.0 - 对私有域名(如
git.internal.company.com),额外检查$GOMODCACHE/cache/download/下对应子目录,一并清理
go mod tidy 不等于清理缓存,但它能缩小清理范围
go mod tidy 只改 go.mod 和 go.sum,不碰 $GOMODCACHE。但它能帮你提前识别“冗余 require”:
- 运行
go mod tidy -v,观察输出中哪些模块被“dropped” - 这些被删掉的模块,大概率已不在任何 import 路径里,可优先从缓存中移除
- 若项目长期未运行
go mod tidy,先执行它,再导出deps.txt,结果更准
容易被忽略的破坏点:GOSUMDB 和 GOPROXY 切换后残留校验数据
缓存损坏常不表现为“找不到包”,而是静默错用旧版本——尤其当你刚切换过代理或关掉 GOSUMDB:
- 检查
go env GOSUMDB和go env GOPROXY是否与当前网络环境匹配 - 若曾用
sum.golang.org校验过某模块,又切到私有代理,旧.info文件可能仍留在$GOMODCACHE/cache/download/里,导致 checksum mismatch - 此时不要全清,定位到具体模块路径,只删对应
.info和.ziphash文件即可











