go clean -modcache仅清$GOPATH/pkg/mod/cache/download,需手动删除$GOPATH/pkg/mod及work-目录并执行go mod download才能彻底解决缓存冲突。

缓存冲突报错不是模块本身写错了,而是本地缓存状态和当前 go.mod 声明不一致——比如 go.sum 里存着旧版本哈希,但 go mod download 又试图拉新版本,校验直接失败。
go clean -modcache 清不干净?删完还得清 GOPATH/pkg/mod
执行 go clean -modcache 只清了 $GOMODCACHE(通常是 $GOPATH/pkg/mod/cache/download),但真正参与构建的是 $GOPATH/pkg/mod 下的 unpacked 模块。这个目录不会被 go clean -modcache 触及。
- 手动删它:
rm -rf $(go env GOPATH)/pkg/mod - 删完立刻跑
go mod download,别等go build自动触发——后者可能复用残留的 partial cache 导致中途卡住或校验失败 - 如果项目用了
go.work,还要顺手删掉$(go env GOPATH)/pkg/mod下以work-开头的临时模块目录
checksum mismatch 错误:GOSUMDB 和代理配置打架
常见现象是报错信息里带 checksum mismatch for module xxx: downloaded from xxx but checksum was yyy。本质是 Go 下载模块时走的路径和 go.sum 记录的来源不一致,导致哈希对不上。
- 检查
GOPROXY是否包含direct:比如export GOPROXY=https://goproxy.cn,direct——没有direct的话,私有模块或本地 replace 会被强制走代理,必然失败 - 确认
GOSUMDB没被设为off或私有地址:运行go env GOSUMDB,正常应是sum.golang.org;若为off,执行go env -w GOSUMDB=sum.golang.org - 私有模块必须配
GOPRIVATE:比如git.example.com/*,否则 Go 仍会尝试查sum.golang.org,而你没权限,就 fallback 到空校验再失败
replace 后 still using old version?路径没生效或被覆盖
replace 写进 go.mod 不代表立刻生效——Go 构建时仍可能从缓存里读旧版,尤其当 go.sum 里还存着旧哈希,或 go list -m all 显示的仍是原路径。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
- 先验证是否真被替换:
go list -m -f '{{.Dir}}' github.com/xxx/yyy输出的路径要是你replace指向的本地目录或 fork 地址 - 如果输出还是原始路径,说明
replace没加载:检查是否在子模块的go.mod里写的(只对子模块生效),或是否被更高层go.work的use声明覆盖 - 删掉
go.sum中该模块所有旧行,再跑go mod tidy,否则旧哈希会阻止新版本写入
go mod verify 失败但项目能编译?缓存绕过了校验
go mod verify 报错而 go build 成功,说明构建过程跳过了完整性检查——大概率是模块已存在于本地缓存,Go 直接用了 unpacked 文件,没重新下载校验。
- 强制重验:先
go clean -modcache,再rm -rf $(go env GOPATH)/pkg/mod,最后go mod verify - 更彻底的办法:临时禁用缓存验证
GOSUMDB=off go mod download,成功后再恢复GOSUMDB并重新go mod verify,看是否还有残留问题 - 注意:
go mod vendor后的vendor/modules.txt必须和go.sum一致,否则go mod verify会忽略 vendor 目录里的内容,只校验缓存
缓存冲突最麻烦的地方在于:它不报明确错误,只是让 go list、go mod graph、甚至 go build 看起来都“正常”,但实际运行时行为异常——因为某次构建偷偷用了缓存里一个没被 go.sum 覆盖的旧 commit。

















