go get 报错 401 或 repository not found 是因未配置私有模块认证,go 不读取 git credential 或 ssh key,需通过 ~/.netrc(推荐)或 go_auth_token 环境变量提供 https 凭据,且 host 必须与模块路径完全一致、token 权限充足、文件权限设为 600。

go get 报错 401 Unauthorized 或 repository not found
这不是网络或代理问题,而是 Go 在拉取私有模块(如 GitHub/GitLab 私有仓库、企业内网 Git)时,没拿到合法凭证。Go 本身不读取 git config credential 或系统 SSH key,它依赖 netrc 或环境变量驱动的认证机制。
- GitHub 私有 repo 常见错误:用 HTTPS 地址但没配 PAT(Personal Access Token),或 PAT 权限不足(缺
read:packages和read:org) - GitLab 私有模块:Token 类型必须是
api,且需勾选read_api和read_repository - 自建 Git 服务(如 Gitea):Go 默认不走 SSH,即使你
git clone能成功,go get仍会失败——它只认 HTTPS + 凭据
配置 ~/.netrc 让 go get 自动带认证头
netrc 是 Go 官方推荐的凭据注入方式,比环境变量更稳定,也避免 token 泄露到 shell history。
- 文件路径必须是
~/.netrc(macOS/Linux)或%USERPROFILE%/_netrc(Windows),权限需设为600(Linux/macOS 执行chmod 600 ~/.netrc) - 每条记录格式严格:
machine <host> login <user> password <token></token></user></host>,例如:machine github.com login username password ghp_abc123...
- 多个主机需分开写,不能合并;
machine后必须是模块导入路径里的 host(如gitlab.example.com,不是https://gitlab.example.com) - 如果模块路径含子路径(如
gitlab.example.com/group/repo),machine仍只写域名,Go 会自动复用
用 GO_AUTH_TOKEN 环境变量临时覆盖(适合 CI/CD)
CI 环境中不方便写 netrc 文件,可用环境变量替代,但注意作用域和优先级。
- 设置方式:
GO_AUTH_TOKEN=ghp_abc123... go get github.com/private/repo - 该变量只对当前命令生效,不会污染全局;若同时存在
netrc和GO_AUTH_TOKEN,后者优先 - 仅支持 HTTPS 协议,对 SSH 地址无效;且只影响 Go 模块拉取,不影响
git clone行为 - GitHub Actions 中建议用
secrets.GITHUB_TOKEN注入,但注意:默认 token 权限有限,私有 org 下模块需额外授权
验证是否生效:用 go list -m -f '{{.Dir}}' <module></module>
别急着跑 go build,先确认模块能解析并下载到本地缓存。这个命令不触发编译,只做模块解析和 fetch,失败时错误信息更干净。
- 成功返回类似
/Users/me/go/pkg/mod/cache/download/github.com/private/repo/@v/v1.2.3.zip - 如果仍报
invalid version,可能是模块未打 tag 或go.mod里module声明与实际路径不一致(比如声明了github.com/org/repo,但仓库实际在gitlab.com/org/repo) - 加
-x参数可看详细请求:go list -x -m github.com/private/repo,会打印 curl 命令,确认 header 是否含Authorization: token ...
真正容易卡住的地方不是 token 本身,而是 token 绑定的 scope、netrc 的权限位、以及模块路径与 machine host 的字符完全匹配——少一个点、多一个端口(如 gitlab.example.com:8443),Go 都不会复用凭据。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











