根本原因是go get默认通过https或ssh拉取代码但未携带认证凭据,导致私有仓库拒绝请求;需配置gitconfig url重写、ssh密钥认证、goprivate前缀匹配及ci环境变量与密钥注入。

go get 访问私有仓库时提示 “repository not found” 或 “permission denied”
根本原因不是 Go 本身不支持私有模块,而是 go get 默认走 HTTPS 或 SSH 协议拉取代码,而没带认证凭据。GitHub、GitLab 等平台对私有仓库会直接拒绝未授权请求。
实操上分两步:告诉 Go 哪些域名走 SSH(绕过 HTTPS 认证),再确保本地 SSH agent 已加载对应密钥。
- 在
~/.gitconfig中配置 URL 重写,例如:[url "git@github.com:"]<br> insteadOf = https://github.com/
- 确认
ssh -T git@github.com能成功连通;若用 GitLab 或自建 Gitea,把域名和用户换成对应值(如git@gitlab.example.com:) - 不要用
https://形式写go.mod里的 module path,比如应写module gitlab.example.com/mygroup/mylib,而不是https://gitlab.example.com/mygroup/mylib
GO111MODULE=on 时 GOPRIVATE 环境变量不起作用
GOPRIVATE 是 Go 模块代理机制的“豁免开关”,但它只在 Go 1.13+ 且 GO111MODULE=on 时生效。如果仍被 proxy(如 proxy.golang.org)拦截,说明匹配规则没生效。
关键点是:它匹配的是 module path 前缀,不是仓库地址,且不支持通配符嵌套。
立即学习“go语言免费学习笔记(深入)”;
- 设为
GOPRIVATE=gitlab.example.com/mygroup/*,不是GOPRIVATE=*.gitlab.example.com - 多个域名用逗号分隔,不能有空格:
GOPRIVATE=gitlab.example.com,github.company.com - 如果 module path 是
gitlab.example.com/mygroup/lib/v2,gitlab.example.com/mygroup/*能匹配,但gitlab.example.com/*不能匹配v2子版本(Go 视其为不同 module)
使用 go install 安装私有命令行工具失败
执行 go install gitlab.example.com/mygroup/cli@latest 报错 “no matching versions” 或 “unknown revision”,通常是因为 Go 尝试从 proxy 查版本,而 proxy 根本看不到私有 repo。
这不是权限问题,是发现机制失效。必须让 Go 直接走 VCS,跳过 proxy 和 checksum database。
- 确保已设
GOPRIVATE覆盖该 module path - 临时禁用校验:
GOSUMDB=off go install gitlab.example.com/mygroup/cli@latest(仅开发阶段,上线前应配好私有 sumdb 或跳过) - 更稳妥的做法:用具体 commit hash 或 tag 替代
@latest,例如@v0.3.1,避免 Go 尝试解析 latest 语义
CI 环境下私有模块拉取失败(如 GitHub Actions / GitLab CI)
本地能跑,CI 上挂,大概率因为 SSH key 没注入,或 GOPRIVATE 没在构建环境中设置。
CI 不共享你的 ~/.gitconfig,也不运行 ssh-agent,得显式配置。
- GitHub Actions:用
webfactory/ssh-agentaction 注入 deploy key,并手动写入.gitconfig(注意 job 间不继承) - GitLab CI:把 SSH_PRIVATE_KEY 加为 masked variable,然后在 script 中 echo 进
~/.ssh/id_rsa并 chmod 600 - 统一建议:所有 CI 脚本开头加
echo "$GOPRIVATE" > /dev/stderr,确认环境变量真被读进去了
私有模块最麻烦的从来不是语法,而是认证链断在哪一环——SSH 配置、gitconfig 重写、GOPRIVATE 前缀、GOSUMDB 策略、CI 权限隔离,漏一个就卡住。别猜,逐层打日志验证。










