根本原因是模块下载路径不统一,导致同一版本被不同代理返回内容不一致的zip包;应确保go_proxy在所有构建阶段全局生效,并与goprivate配置对齐,避免部分模块走代理、部分直连或404。

为什么 go mod download 会报 “module X: checksum mismatch”?
根本原因不是校验失败本身,而是不同模块在下载时走了不同代理路径——比如一个走 https://proxy.golang.org,另一个走公司内网的 https://goproxy.example.com,导致同一版本模块被下载了两份内容不一致的 zip 包(尤其当内网代理缓存过期或未同步 vendor 信息时)。Go 的 checksum 验证机制会立刻拒绝这种不一致。
如何统一所有模块的代理来源?
关键不是“设置代理”,而是确保 GO_PROXY 环境变量对整个构建生命周期生效,包括 go mod tidy、go build 和依赖解析阶段。常见错误是只在 shell 启动时设一次,但 IDE 或 CI 环境没继承该变量。
- 本地开发:在
~/.bashrc或~/.zshrc中写死export GO_PROXY=https://goproxy.cn,direct(推荐国内用goproxy.cn,支持directfallback) - CI/CD(如 GitHub Actions):必须显式在每个
run步骤前设置,不能只设在 setup-go 步骤里 - IDE(如 GoLand):检查「Preferences → Go → GOPATH and GOPROXY」是否勾选「Use GOPROXY environment variable」,否则它会忽略你的 shell 设置
go env -w 写进配置后为什么还是不生效?
go env -w GO_PROXY=... 确实会写入 ~/go/env,但它只影响 go 命令自身读取的环境变量,不覆盖系统级或 shell 的 GO_PROXY。如果 shell 已定义同名变量,优先级更高,会覆盖 go env 的设置。
- 执行
go env GO_PROXY查看当前实际生效值,而不是只信cat ~/go/env - 若输出和预期不符,运行
unset GO_PROXY再试一次go env -w,避免环境变量污染 - Windows 用户注意:
go env -w在 PowerShell 和 CMD 下行为不同,建议统一用 PowerShell 并重启终端
哪些模块会偷偷绕过 GO_PROXY?
只有明确标记为私有模块(匹配 GOPRIVATE 模式)的路径才跳过代理。但很多人误以为 github.com/myorg/* 自动私有——其实必须手动配置:
- 运行
go env -w GOPRIVATE=github.com/myorg/*,gitlab.internal.net/* - 多个 pattern 用逗号分隔,不能有空格
- 如果 private 模块依赖了公共模块(如
golang.org/x/net),而GO_PROXY又设成仅内网地址,就会卡住——此时需保留direct或用支持 fallback 的代理(如https://goproxy.cn,direct)
真正麻烦的从来不是代理地址本身,而是 GOPRIVATE 和 GO_PROXY 的组合逻辑没对齐,导致一部分模块走代理、一部分直连、一部分 404,checksum mismatch 只是最后暴露的症状。











