Go mod download 报 401 或 repository not found 的主因是凭证缺失,需配置 ~/.netrc(Linux/macOS)或 %USERPROFILE%\_netrc(Windows),权限设为 600,内容仅含 machine、login、password 三字段,且 machine 域名须与模块导入路径完全一致。

Go mod download 报 401 或 repository not found 怎么办
私有 Git 仓库(比如 GitHub Enterprise、GitLab Self-Hosted、Bitbucket Server)用 go mod download 拉包失败,绝大多数情况是 Go 没拿到凭证——它不读 ~/.gitconfig 的 credential 配置,也不走 SSH agent,只认 ~/.netrc 或环境变量注入的 token。
常见错误现象:go: github.example.com/org/private-module@v0.1.0: reading github.example.com/org/private-module/go.mod at revision v0.1.0: 401 Unauthorized,或者直接 repository not found(尤其用 HTTPS + token 时路径拼错会伪装成 404)。
-
~/.netrc必须权限为0600,否则 Go 会静默忽略(Linux/macOS 下chmod 600 ~/.netrc) - 机器上多个私有域名时,
machine行必须和模块导入路径里的 host 完全一致(比如模块是gitlab.internal.company.com/group/lib,那machine就得写gitlab.internal.company.com,不能写https://gitlab...) - 如果仓库要求 Basic Auth,用户名填
git或任意非空字符串都行,密码填 Personal Access Token(PAT);若用 OAuth2 token,需确认该 token 有read_package_registry或对应 scope
Netrc 文件格式与 Go 的解析边界
~/.netrc 看似简单,但 Go 对它的解析非常严格:只支持 machine、login、password 三字段,不支持 default、account,也不识别注释(# 开头行会导致整行失效)。
正确示例:
立即学习“go语言免费学习笔记(深入)”;
machine github.example.com login git password ghp_abc123xyz...
容易踩的坑:
- 密码含特殊字符(如
/、@、:)不用 URL 编码,Go 原样传给 HTTP Basic Auth,只要 Git 服务端能接受即可 - 同一域名多个 token(比如 dev/staging/prod 环境不同 token),Go 只取第一个匹配的
machine块,不会 fallback - Windows 用户注意:
%USERPROFILE%\_netrc是等效路径,但文件名是_netrc(不是.netrc),且换行符必须是\n(LF),CRLF 会触发解析失败
替代方案:用 GOPRIVATE + GONETRC 环境变量绕过 netrc 限制
当无法写入 ~/.netrc(CI/CD 容器、共享宿主机),或需要动态切换凭证时,可改用环境变量驱动。
关键组合:
-
GOPRIVATE=github.example.com,gitlab.internal.company.com:告诉 Go 这些域名下的模块跳过 checksum 验证,允许走自定义凭证 -
GONETRC=/path/to/custom.netrc:指定非默认 netrc 路径(Go 1.21+ 支持),适合临时凭证文件 - 更轻量做法:直接设
GIT_AUTH_TOKEN=ghp_...并在go env -w中配置,但仅部分 Go 版本(1.22+ 实验性支持)和特定 Git 托管商有效,稳定性不如 netrc
注意:GOPRIVATE 必须包含完整域名,子域名不自动继承(GOPRIVATE=company.com 不覆盖 gitlab.company.com)。
调试凭证是否生效的最快方法
别等 go mod tidy 跑完再猜,用 go list -m -json 直接触发模块元数据拉取,并观察底层 Git 是否成功。
实操步骤:
- 删掉
go.sum和pkg/mod/cache里对应模块缓存(避免命中旧失败记录) - 运行
go list -m -json gitlab.internal.company.com/group/lib@v0.1.0 - 若仍报错,加
GIT_TRACE=1看 Git 底层调用:GIT_TRACE=1 go list -m -json ...,输出里出现remote: Invalid username or password就说明 netrc 没生效;出现fatal: could not read Username则是 netrc 权限或格式问题
最隐蔽的坑是:公司防火墙或代理拦截了 go get 的 HTTPS 请求,返回假 401,此时 curl -v https://github.example.com/api/v3/ 能更快定位是网络策略问题而非凭证问题。










