go.sum 不锁定版本,仅校验依赖完整性;它记录各模块版本的 SHA256 哈希(h1:开头),供构建时验证代码未被篡改,实际版本由 go.mod 中的 require、GOPROXY 和本地缓存共同决定。
很多人误以为 go.sum 能像 package-lock.json 或 Pipfile.lock 那样锁定模块版本——其实不能。go.sum 只记录每个模块版本对应的内容哈希(h1: 开头的 SHA256),用于 go build、go test 时校验下载的代码是否被篡改或意外变更。真正决定“用哪个版本”的是 go.mod 中的 require 语句和 go get 的行为。
执行 go build 时,Go 并不读取 go.sum 来选版本,而是:
go.mod 中的 require,比如 github.com/gin-gonic/gin v1.9.1
$GOPATH/pkg/mod 是否已存在该版本;若无,则通过 GOPROXY(默认 https://proxy.golang.org)下载go.sum
这意味着:如果你删掉 go.sum,再运行 go build,Go 会重新下载相同版本(只要 go.mod 没变、代理没返回不同内容),并生成新的 go.sum 行——但内容应一致。若不一致,说明源已被

Go 默认只在 go.mod 中显式声明直接依赖。间接依赖(transitive)版本由 Go 自动推导,可能随上游更新而变。要锁定全部依赖(包括间接的),需:
go mod vendor:把所有依赖复制进 vendor/ 目录,后续构建加 -mod=vendor 参数即可完全离线、确定性构建go mod graph | grep + go get 显式拉取关键间接依赖版本,再 go mod tidy 固化到 go.mod
go.sum 校验;若想跳过(仅调试),可用 GOINSECURE 或 GOSUMDB=off,但生产环境禁止示例:强制升级某间接依赖并锁定
go get github.com/sirupsen/logrus@v1.9.3 go mod tidy
这会让 Go 把 logrus v1.9.3 写入 go.mod(即使你没直接 import),并更新 go.sum 中对应哈希。
典型报错如:verifying github.com/xxx@v1.2.3: checksum mismatch,原因通常是:
go.sum 记录的是旧哈希,而代理返回了新内容修复方式(按安全优先级排序):
go clean -modcache 清空本地缓存,再 go mod download 看是否仍报错go mod verify 查看差异,然后 go mod tidy -v 自动更新 go.sum
go.sum 替换哈希值——但必须确保来源可信go.sum 不该手动维护,它的生成和校验是 Go 工具链自动完成的闭环。唯一需要人干预的,是当哈希不匹配时判断「该信谁」。