“permission denied (publickey)”是git命令执行ssh克隆失败所致,根本原因在ssh密钥链断裂:ssh-agent未启动或未加载私钥、~/.ssh/config中host别名与模块路径不匹配、user未设为git、私钥权限非600、goprivate未精确匹配模块前缀(如需写成gitlab.example.com/*),或ci环境未注入密钥。

go mod拉取私有包时提示“permission denied (publickey)”
这不是 Go 报的错,是底层 git 命令执行 git clone git@gitlab.example.com:team/repo.git 失败导致的。Go 只负责调度,认证完全交给系统 git 和 SSH 工具链。
常见原因和实操建议:
- SSH agent 没启动或没加载密钥:
ssh-add -l为空?运行ssh-add ~/.ssh/id_ed25519(换成你实际私钥路径) -
~/.ssh/config中 Host 别名不匹配模块路径:比如模块路径是gitlab.example.com/team/repo,但~/.ssh/config写的是Host gitlab→ 应改为Host gitlab.example.com - 远程 Git 服务用户不是
git:检查~/.ssh/config是否明确写了User git(GitLab/SSH 默认要求该用户) - 权限太宽松:
chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_*,否则 OpenSSH 会直接拒用密钥
设置了 GOPRIVATE 还报 “unknown revision”
说明 Go 已跳过 proxy 和 sumdb,但 git 层根本没连上仓库——它甚至没走到认证那步,而是解析 URL 或网络连接就失败了。
排查重点:
- 确认
go.mod里module行路径与你期望的 import 路径一致,且能映射到真实 Git 地址。例如模块路径为gitlab.example.com/team/repo,对应仓库地址必须是git@gitlab.example.com:team/repo.git或通过git config重写后能等价转换 - 验证
git ls-remote git@gitlab.example.com:team/repo.git是否成功返回 refs。失败则说明 SSH 配置未生效,和 Go 无关 -
GOPRIVATE值必须精确匹配模块路径前缀:写成gitlab.example.com不行,得是gitlab.example.com/**(推荐)或gitlab.example.com/*;含端口时(如gitlab.example.com:2222)必须带端口
go get 用 HTTPS 却卡在 “terminal prompts disabled”
这是 Git 拒绝弹出密码框的典型表现,Go 调用 git 时默认禁用交互式输入。
两个可靠解法:
- 切到 SSH:改
go.mod中 module 路径为 SSH 格式(git@gitlab.example.com:team/repo),并配好~/.gitconfig的insteadOf规则 - HTTPS + Token:用 Personal Access Token 构造 URL,例如
https://token:x-oauth-basic@gitlab.example.com/team/repo.git,然后在go.mod中写module gitlab.example.com/team/repo,再确保GOPRIVATE已覆盖该域名
CI 环境下 SSH 密钥不生效
本地 OK、CI 报错,大概率是环境隔离问题:SSH agent 不跨会话,CI runner 往往是干净 shell,ssh-agent 未启动,或密钥没注入。
关键动作:
- CI 脚本开头加:
eval $(ssh-agent -s) && ssh-add (把密钥内容存为变量注入) - 避免用
~/.ssh/id_rsa硬路径:CI 容器中家目录可能为空,应显式指定密钥路径或从变量读取 - 检查 CI 环境是否禁用了
ssh-agent或限制了 socket 文件路径(某些 Kubernetes Pod 默认删掉/tmp) - 别依赖
~/.netrc:Go 和 git 都不读它,HTTPS 场景下必须用git credential或 URL 内嵌 token
git 层。只要 git clone 在当前环境下能通,go mod tidy 就不会卡在这一步。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











