go mod download静默失败主因是GO_PROXY配置错误,国内应设为https://goproxy.cn,direct并配GO_PRIVATE处理私有模块,且需go mod tidy同步go.sum,否则构建报checksum mismatch。

GO_PROXY 配置不对,go mod download 就会静默失败
国内环境默认 GO_PROXY=https://proxy.golang.org,direct 基本不可用:前者常被重置或超时,后者因无认证直接被模块服务器拒绝,但错误提示极弱,容易误判为“网络没问题只是慢”。
- 运行
go env -w GO_PROXY=https://goproxy.cn(或https://goproxy.io)立即生效 - 验证是否生效:
go env GO_PROXY输出必须是你刚设的地址,不是默认值 - 内网场景不能连外网?必须配
GO_PRIVATE+direct,例如:go env -w GO_PRIVATE=git.internal.company.com/* -
go mod download -x日志只显示 proxy 请求路径,不暴露direct失败细节;真要看 fallback 行为,得加GODEBUG=http2debug=2 go mod download
改了 go.mod 却没同步 go.sum,构建时爆 checksum mismatch
go mod download 不会刷新 go.sum 中已存在的哈希记录——它只把源码存进缓存,不校验也不重写。你手动改了版本号,但 go.sum 还留着旧哈希,go build 一读就报错。
- 安全做法:每次修改
go.mod后,必须跑go mod tidy,它会重新拉取、校验、更新go.sum - 如果只想预下载不碰
go.sum(比如 CI 中提前缓存),得接受后续构建可能失败——尤其当作者重推 tag 或删 zip 包 -
go.sum必须提交 Git,且每次go mod tidy后要人工确认新增条目来源是否可信,比如突然出现github.com/xxx/yyy@v0.0.1,得查是不是内部库
go mod download 和 vendor 混用,构建行为完全不可控
很多人想用 go mod download 替代 go mod vendor 实现“离线构建”,但两者定位根本不同:download 只存源码到全局缓存($GOPATH/pkg/mod),而 vendor 是把依赖复制进项目目录。混用会导致本地构建和 CI 构建结果不一致。
- 千万别在
vendor存在时还跑go mod download然后删vendor——go build默认优先读vendor,缓存下载白做 - CI 镜像构建中,
go mod download必须放在COPY go.mod go.sum .之后、COPY . .之前,否则每次构建都重复下载 - 如果真要离线构建,用
go mod vendor,而不是依赖download+-mod=vendor的组合
依赖扫描漏掉间接依赖,govulncheck 默认只扫表面
govulncheck 默认只检查 go.mod 里显式声明的直接依赖,但真实漏洞往往藏在 // indirect 引入的传递依赖里,比如 golang.org/x/net 被某个日志库悄悄拉进来,不加参数就扫不到。
- 必须跑两遍:
govulncheck ./(业务代码链路) +govulncheck -test ./(测试代码链路,常暴露深层依赖) - 输出里的
GO-XXXX-XXX是 Go 官方编号,不是 CVE,别拿它去搜 NVD -
go list -m all | grep -E "(golang\.org/x|github\.com/.*\.(sql|http|crypto))"手动盯高频风险包,再用go mod graph | grep 包名查谁引入了它 -
go mod verify必须进 CI 第一行,配合GOSUMDB=sum.golang.org强制远程校验,防中间人污染
go.mod 忘了 tidy、配了 GO_PROXY 没验证、扫漏洞没加 -test、或者以为 download 就等于“准备好构建了”——这些点不盯死,风险就一直在。

















