go.sum 文件记录模块校验和而非锁定版本,真正锁定依赖的是 go.mod 的 require 语句与 go.sum 校验协同完成;其变更常见于首次构建、多版本引入、tag 重写、GOSUMDB 关闭等场景。

Go 的 go.sum 文件不是“锁文件”,它不锁定版本,而是记录模块下载时的校验和;真正锁定依赖版本的是 go.mod 中的 require 语句 + go.sum 的完整性校验协同完成的。
为什么 go.sum 会变,但 go.mod 没改?
常见于以下场景:
- 首次运行
go build或go test时,Go 会自动填充go.sum中缺失的间接依赖(// indirect)校验和 - 同一模块不同版本被多个路径引入(例如
v1.2.0和v1.3.0同时存在),Go 会为每个版本单独记录校验和 - 模块发布者重写了 tag(极不推荐),导致相同版本号对应不同内容,
go.sum会拒绝旧校验和并报错checksum mismatch - 本地启用了
GOSUMDB=off或替换了 sumdb,也会绕过校验逻辑,导致go.sum内容与公共 sumdb 不一致
go mod tidy 会修改哪些文件?如何安全执行?
go mod tidy 是同步依赖状态的核心命令,它会:
- 读取当前代码中所有
import路径,补全缺失的require条目到go.mod - 移除未被任何
import引用的require行(包括// indirect标记的) - 更新
go.sum:添加新模块校验和、删除不再需要的校验和条目 - 不会升级已有模块版本(除非显式
go get),也不会降级
建议在执行前确认:
立即学习“go语言免费学习笔记(深入)”;
- 已提交当前代码变更(避免 tidy 混淆真实依赖变更)
- CI 流程中始终使用
go mod tidy -v并检查退出码,失败即中断构建 - 若需保留某个间接依赖(如用于
go:generate工具),应在go.mod中显式require并加// indirect注释(Go 1.17+ 支持)
校验失败:checksum mismatch 怎么定位和修复?
错误典型形式:
verifying github.com/sirupsen/logrus@v1.9.0: checksum mismatch downloaded: h1:...abc123... go.sum: h1:...def456...
原因通常是:
- 模块作者强制推送了已发布的 tag(破坏性操作)
- 你本地代理或 GOPROXY 返回了被篡改/缓存污染的 zip 包
- 模块本身未发布到官方 proxy,而你配置了不可信的私有 proxy
修复步骤:
- 运行
go clean -modcache清空本地模块缓存 - 临时禁用 proxy:
GOPROXY=direct go mod download直连 origin - 对比
go.sum中记录的校验和与 sum.golang.org 查询结果是否一致 - 若确认是模块方问题,可临时 fork 并
replace到可信 commit(写入go.mod)
团队协作中容易忽略的三个细节
go.sum 必须提交进 Git —— 它不是“生成文件”,而是依赖完整性的关键证据。遗漏会导致:
- 不同开发者本地
go.sum不一致,CI 构建通过但本地构建失败 - CI 使用
go mod verify时因缺少校验和而报错 - 安全扫描工具(如
govulncheck)无法准确映射漏洞到实际使用的模块版本
另外注意:
-
go mod vendor会把模块源码复制进vendor/,但go.sum仍需保留且必须与 vendor 内容一致;可用go mod vendor -v验证 - Go 1.21+ 默认启用
GOSUMDB=sum.golang.org,不建议关闭,除非明确使用私有 sumdb - 不要手动编辑
go.sum:校验和格式敏感,出错会导致整个模块树校验失败










