go mod download 默认访问 proxy.golang.org 是因 goproxy 默认值为 https://proxy.golang.org,direct,它优先走代理下载模块归档,仅当代理返回404/410时才 fallback 到 direct 直连;replace 不影响 download 行为,仅作用于构建阶段。

为什么 go mod download 总是去 proxy.golang.org?
因为 Go 默认启用了模块代理(GOPROXY),只要环境变量没显式覆盖,就走官方代理。这不是“缓存”或“配置错误”,而是设计行为——即使你本地有源码、也写了 replace,go mod download 仍会先尝试从代理拉取所有依赖的 zip 包和 go.mod 文件。
- 代理地址由
GOPROXY决定,默认值是https://proxy.golang.org,direct -
direct是兜底项:仅当代理返回 404 或 410 时才直连原始仓库(如 GitHub) -
go mod download不受replace影响——它只管“下载模块归档”,不管后续构建用哪个路径
怎样让 go mod download 走私有镜像或本地路径?
必须改 GOPROXY,不能靠 replace 或 go mod edit -replace。常见有效写法:
- 指向国内镜像:
GOPROXY=https://goproxy.cn,direct(注意逗号后无空格) - 禁用代理、强制直连:
GOPROXY=direct(此时要求所有模块仓库可直连,如 GitHub 可能超时) - 混合策略(推荐):
GOPROXY=https://goproxy.cn,https://proxy.golang.org,direct,失败后自动降级 - 完全离线?设
GOPROXY=off,但要求所有模块已存在pkg/mod/cache中,否则报错module xxx: not found
临时生效可加 -x 看实际请求 URL:GOPROXY=https://goproxy.cn go mod download -x,输出里会出现 GET https://goproxy.cn/xxx/@v/xxx.zip。
replace 和 download 的关系到底是什么?
replace 完全不干预下载阶段,只影响构建和导入解析。它在 go build、go test 时生效,告诉 Go “这个模块名,实际用我指定的本地路径或另一模块替代”。但 go mod download 还是照常去代理下原始模块。
- 典型误操作:写了
replace github.com/foo/bar => ./bar,然后跑go mod download发现没拉本地代码——这是对的,download就不该理replace - 想让本地代码参与构建又避免网络下载?先
go mod download拉下来,再replace指向本地,后续命令才用本地 - 若本地模块没发布过 tag,
go mod download会失败(因为代理找不到对应版本),此时必须设GOPROXY=direct或提前go mod edit -require加伪版本
更新依赖路径后为什么 go list -m all 还显示旧地址?
因为模块路径记录在 go.sum 和 go.mod 的 require 行里,不是运行时动态查的。手动改 GOPROXY 只改变下载行为,不重写这些文件。
- 要刷新依赖列表,得触发重新解析:删掉
go.sum+go mod tidy(会按新GOPROXY重新下载并写入校验和) -
go list -m all显示的是当前go.mod声明的模块路径,不是实际来源;真正来源要看go list -m -f '{{.Dir}}' xxx返回的磁盘路径 - 如果
replace指向一个未go mod init的本地目录,go list -m会报错no module found,必须确保该目录有合法go.mod
最易忽略的一点:GOPROXY 设置对 go get 同样生效,但 go get -u 会同时修改 go.mod 中的版本号——如果你只想换下载源,别混用 -u,否则可能意外升级版本。











