根本原因是go默认启用sum.golang.org校验服务且不支持fallback,goproxy=direct仅跳过代理拉取但不关闭校验,gosumdb=off才是唯一能彻底禁用校验的开关。

自建代理节点故障时,go mod download 会卡在 checksum 验证阶段,根本原因是 Go 默认启用 sum.golang.org 校验服务,而该服务不可绕过、不支持 fallback,一旦网络路径不通(比如代理节点宕机或证书异常),所有模块下载都会失败——不是超时,是直接拒绝校验通过。
为什么 GOPROXY=direct 仍会触发校验失败
设置 GOPROXY=direct 只跳过代理拉取,但不关闭校验。Go 仍会尝试连接 sum.golang.org 获取和比对 checksum;若该域名无法解析、TLS 握手失败、或返回非 200 响应(如 502/403),go mod download 就会报错:verifying github.com/user/repo@v1.2.3: checksum mismatch 或更隐蔽的 Get "https://sum.golang.org/lookup/...": dial tcp: i/o timeout。
-
GOINSECURE对 sumdb 无效,只影响 module proxy 的 TLS 校验 -
GOSUMDB=off是唯一能彻底禁用校验的开关,但需显式设置,且必须在go mod命令执行前生效 - 若同时设了
GOSUMDB=off和GOPROXY=direct,Go 不再发起任何远程校验请求,完全本地信任
GOSUMDB=off 的实际使用边界
它不是“不安全”,而是把校验责任移交给你:你得确保 go.sum 文件本身来自可信来源(如 git commit 记录、CI 构建产物归档),且未被篡改。常见合规场景中,只要团队内部有固定 go.sum 提交策略,GOSUMDB=off 是稳定可接受的。
- CI 环境推荐:在构建脚本开头加
export GOSUMDB=off,避免因外部服务抖动导致构建失败 - 离线开发环境必须启用,否则
go mod tidy直接阻塞 - 不能只在终端临时 export,Docker 构建、Makefile 子 shell、IDE 启动的 go 进程都需各自设置
-
GOSUMDB=off不影响go get -u的升级逻辑,只跳过校验环节
如何验证校验链是否真正断开
不要只看 go mod download 是否成功,要确认 Go 是否真的没连 sumdb。最可靠方式是抓包或日志观察:
- 运行
go env -w GODEBUG=http2debug=2,再执行go mod download,搜索输出中是否出现sum.golang.org的 CONNECT 或 GET 请求 - 临时屏蔽 sumdb:在 hosts 文件加
127.0.0.1 sum.golang.org,然后运行go mod download—— 若仍成功,说明GOSUMDB=off已生效;若报错dial tcp 127.0.0.1:443: connect: connection refused,说明还在尝试连接 - 注意:某些企业防火墙会劫持 DNS 返回假 IP,导致连接看似成功但校验失败,此时需结合 TLS 握手日志判断
真正麻烦的不是关掉校验,而是让所有构建上下文(shell、CI job、容器、IDE)都一致地应用 GOSUMDB=off;漏掉任意一个环节,就会在某个角落突然失败,而且错误信息不指向配置问题,只显示校验失败。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











