go.sum是模块校验快照,仅用于验证go.mod中声明模块的内容完整性;校验失败会中止构建,常见于代理污染或版本撤回;须提交至Git并禁止CI中自动生成,编辑应通过go get而非手动修改哈希。

go.sum 文件本质是模块校验快照,不是依赖树描述文件
它不决定哪些模块会被加载,只在 go build、go test 等命令执行时用于验证 go.mod 中声明的每个模块版本内容是否被篡改。一旦校验失败,Go 会直接报错并中止,例如:
verifying github.com/sirupsen/logrus@v1.9.3: checksum mismatch downloaded: h1:2j0z74W2FwZV5xgBqkLdZyQsKZaZaZaZaZaZaZaZaZa= go.sum: h1:1jXz74W2FwZV5xgBqkLdZyQsKZaZaZaZaZaZaZaZaZa=
这种错误通常意味着:你本地缓存的模块内容和官方代理返回的不一致(比如代理被污染、网络中间件重写、或模块作者撤回了已发布版本)。
手动修改 go.sum 很危险,但有时不得不做
常见被迫编辑场景包括:模块作者撤回 tag、私有仓库 URL 变更、或切换了 Go 代理后校验值不匹配。此时不能直接删 go.sum 重生成——那会导致所有间接依赖的校验丢失,下次拉取可能引入恶意包。
- 优先用
go mod download -json检查具体哪个模块校验失败 - 确认来源可信后,用
go mod verify单独校验目标模块 - 若需更新某行,应运行
go get -u=patch或go get,让 Go 自动重写对应行@ - 绝对避免用文本编辑器直接替换
h1:xxx值——Go 不校验该哈希是否真对应内容,只比对字符串,填错照样过检但失去保护意义
CI/CD 中 go.sum 必须提交且禁止自动生成
很多团队误以为 CI 中跑 go mod tidy 就够了,结果发现不同机器拉到的间接依赖版本不一致。根本原因是:go.sum 未纳入 Git,导致每次构建都重新解析依赖图并生成新校验值,而 Go 1.18+ 默认启用 GOPROXY=direct 时行为更不可控。
立即学习“go语言免费学习笔记(深入)”;
-
go.sum必须和go.mod一起git add提交 - CI 脚本开头加
git diff --quiet go.sum || (echo "go.sum changed but not committed"; exit 1)防遗漏 - 禁止在 CI 中执行
go mod tidy -e或任何会静默更新go.sum的操作 - 私有模块若用
replace,其校验值仍来自原始 module path,不是 replace 后的路径——这点常被忽略,导致本地能过、CI 报校验错
go.sum 行格式藏着关键兼容线索
每行形如:github.com/golang/freetype v0.0.0-20170609003504-e23772dcdcbe h1:4VfRnJfGx1yDc6A5PzYbRrYJm1XoAJCvT76O6lXuJQ4=
注意第二字段的 v0.0.0- 时间戳格式,说明该模块无规范语义化版本;第三字段以 h1: 开头表示使用 SHA-256 哈希(Go 1.11+ 默认),旧项目若混着 h12:(SHA-512)或 go:sum 格式,说明曾被低版本 Go 处理过,建议统一升级 Go 并重新生成。
真正容易被忽略的是:同一个模块不同版本可能共存于 go.sum,尤其当 go.mod 里有多个 require 指向同一模块的不同 commit —— Go 不会自动去重,每行都独立校验。这意味着删掉一个 require 后,对应 go.sum 行不会自动消失,得靠 go mod tidy 清理,但前提是模块确实不再被任何路径引用。










