刚git pull就冒出一串红字:fatal: unable to access 'https://git.example.com/group/project.git/': Could not resolve host: git.example.com,很多刚上手Git的同学一看unable to access就慌,觉得是账号密码错了,或者远程仓库被别人删了,胆子小的甚至会把本地仓库删了重新 clone。其实这条报错已经把原因写得非常直白:你的电脑根本不认识git.example.com这个域名,没法把它翻译成一台真实服务器的IP地址。这就是典型的 Git 远程仓库域名解析失败。
这类问题在我实际排查中碰到过很多次,场景也五花八门:有人在家里能 clone,一到公司就失败;有人昨天还好好的,今天突然连不上某个代码托管平台;还有人是整个团队同时报错,但访问其他网站又一切正常。域名解析失败不是一个“坏消息”,它是一张很明确的线索卡,告诉你问题基本出在网络寻址这一层,而不是出在Git服务本身。下面把自己这些年整理的排查套路完整写一遍,按5步走,每一步都有命令、有判断标准、有常见的坑。
1. 先读懂这条报错:谁在替你“喊冤”
1.1 一次 Git 远程操作背后的完整链路
先别急着敲命令,花30秒搞清楚 Git 执行远程操作时到底发生了什么。比如你执行git clone https://git.example.com/group/project.git,数据包不是直接奔着服务器去的。它要经过下面这几步:
- 解析 URL:Git 识别出主机名是
git.example.com,协议是 HTTPS。 - 域名解析:操作系统调用解析器,去问配置好的 DNS 服务器“
git.example.com对应哪个IP”。 - 建立 TCP 连接:拿到IP后,和
443端口建连。 - TLS 握手/HTTP 传输:确认证书、交换数据。
报错说Could not resolve host,说明卡在第二步。域名没解析出来,后续的 TCP 连接、TLS 握手根本不会发生。所以再怎么检查账号密码、SSH key 都没用,那都是后面的事。
1.2 三个最容易被混淆的“嫌疑人”
实际排查时,我经常看到有人把下面三种情况混为一谈:
| 报错特征 | 真实含义 | 下一步 |
|---|---|---|
Could not resolve host: xxx | 域名解析失败,DNS 这一层出问题 | 先查本机DNS配置、网络连通性 |
Connection refused或Connection timed out | 域名能解析,但连不上服务器的端口 | 查防火墙、服务器状态、端口监听 |
Authentication failed/Permission denied | 域名和网络都正常,账号权限不够 | 查凭据、SSH key、远端权限 |
如果你拿到的报错是Could not resolve host,就别去折腾 SSH key 了,问题根本还没到那一步。判断标准就一句话:先解决“能不能找到路”的问题,再解决“能不能进门”的问题。
2. 第一步:确认本机网络到底通不通
2.1 先用 ping 探一轮
很多人一上来就nslookup,但域名解析失败的原因可能是底层网络已经断了。这时候再查 DNS 属于白费力。我习惯先做一轮“由近到远”的连通性测试:
# 先ping网关,确认局域网通 ping 192.168.1.1 # 再ping一个公网IP,确认出口链路通 ping 203.0.113.10 # 同时观察域名解析情况 ping git.example.com这里有个细节:ping git.example.com能通,不代表解析全好;ping命令本身也要走域名解析,如果它能通,说明解析和链路至少是好的。如果前两条通、第三条报“unknown host”,那网络是通的,问题锁定在解析环节。
2.2 检查网络环境是否发生了切换
这一步很多人会忽略。笔记本从家里带到公司、从有线切到无线、手机热点切回办公网,都会导致 DNS 配置完全变化。某些无线网络会把特定域名的解析结果劫持或屏蔽,换个网络环境问题立刻消失。
我踩过不少次坑:开发机上手动把 DNS 写死成旧环境的地址,结果一到新网络就解析失败,域名查不到任何记录。遇到域名解析失败,先看右上角网络图标,确认当前连的是不是预期中的那个网络。如果你切换了网络就出问题,大概率是网络侧下发的 DNS 配置和当前环境不匹配。
2.3 用 IP 直连做一次强对比
如果ping git.example.com不行,但我能从别的途径拿到目标服务器的真实IP,我会直接用 IP 做一次连通性确认:
git clone https://203.0.113.10/group/project.gitIP 直连能通,说明链路完全没问题,域名解析是唯一故障点。IP 直连也会带来新问题,比如证书和域名不匹配、某些托管平台拒绝基于 IP 的访问请求,这些先不管,只把它当诊断手段。诊断完记得清理掉这个临时 remote:
git remote remove origin3. 第二步:对域名做专项解析检查
3.1 三个命令看穿解析结果
网络确认没问题之后,就该进入 DNS 专项排查了。我在类 Unix 系统上最常用的是nslookup和dig,在 Windows 上用nslookup或 PowerShell 的Resolve-DnsName。三个命令各有用途:
# nslookup:跨平台通用,胜在直观 nslookup git.example.com # dig:信息更详细,能看权威服务器、TTL dig git.example.com # getent:直接问系统解析库,和Git实际走的路径一致 getent hosts git.example.com这里我特别推荐getent hosts。因为这个命令查的就是系统底层解析流程,和 Git 走的是同一套逻辑。有些时候nslookup查出来是好的,但getent查出来错误,说明问题出在本机 hosts、/etc/nsswitch.conf或者本地解析服务的缓存上。
3.2 怎么解读返回的 IP 结果
拿到解析结果之后,按下面的规则去判断:
- 完全没有返回记录,提示 NXDOMAIN:域名不存在或 DNS 服务器查不到,检查域名是否写错,或者 DNS 服务器是否可靠。
- 返回一个 IP,但 ping 不通:说明域名本身能解析,问题在路由、防火墙或服务器状态。
- 返回多个 IPv6 和 IPv4 地址:关注是不是 IPv6 优先策略导致连接卡死。
- 返回的 IP 跟之前完全不一样:可能是 CDN 调度变化,也可能是解析结果被污染,需要提高警惕。
某次我排查一个“一会儿通一会儿不通”的问题,就是 IPv6 地址拿到了,但网络环境其实不支持 IPv6,系统偏偏优先走 v6,导致连接超时。Git 报错虽然不是Could not resolve host,而是Connection timed out,但检查域名解析时顺手看看 v6/v4 记录,能少走不少弯路。
3.3 会重复 DNS 请求的 curl 工具
另外一个实用的检查手段是 curl:
curl -v https://git.example.com --connect-timeout 10如果 curl 能正常返回页面内容或 Git 协议信息,而 Git 操作失败,问题就不在域名解析,而在 Git 配置或仓库地址本身。curl -4和curl -6可以分别强制走 IPv4/IPv6,定位上面说的“IPv6优先导致连接超时”问题特别好用。
4. 第三步:检查并修正本机 DNS 配置
4.1 类 Unix 系统怎么看当前 DNS
到了这一步,基本可以确定是 DNS 配置的问题了。在 Linux 上先看/etc/resolv.conf:
cat /etc/resolv.conf正常情况下会看到类似这样的内容:
nameserver 192.168.1.1 nameserver 223.5.5.5文件里没有nameserver,或者写了一个已经失效的内网地址,那解析失败就是必然结果。resolvectl status或systemd-resolve --status可以看 systemd-resolved 托管时的实际生效配置,注意有些系统虽然resolv.conf里写了,但实际解析走的是 systemd-resolved,改完/etc/resolv.conf未必生效。
macOS 上用网络设置面板查看 DNS 比较直观,命令行可以用:
scutil --dns4.2 Windows 下怎么检查
Windows 用户运行:
ipconfig /all重点看“DNS 服务器”那一项。如果是 0.0.0.0、自动获取异常或者指向了已经失效的地址,需要到“网络和 Internet 设置 → 更改适配器选项 → 右键网卡 → 属性 → IPv4 → 属性”里修正 DNS 服务器。
4.3 修改 DNS 配置的正确姿势
修改常见公共 DNS 可以直接编辑/etc/resolv.conf:
sudo vim /etc/resolv.conf # 内容修改为 nameserver 223.5.5.5 nameserver 114.114.114.114但注意,如果系统由 NetworkManager 管理,重启网络会把/etc/resolv.conf覆盖回原样。持久化修改建议去网络连接设置里配置,或者用nmcli调整:
nmcli con mod "你的连接名" ipv4.dns "223.5.5.5 114.114.114.114" nmcli con up "你的连接名"Windows 用户在网卡属性界面里把 DNS 改成自动获取或者手动填一个可用的公共 DNS 都行。改完之后不要忘记刷新 DNS 缓存:
# Linux(systemd-resolved) systemd-resolve --flush-caches # macOS sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder # Windows ipconfig /flushdns改完 DNS、刷完缓存再执行一次git ls-remote https://git.example.com/group/project.git,如果能返回分支和提交信息,问题就当场解决。
5. 第四步:HOSTS 直写域名,临时方案怎么用
5.1 hosts 文件的位置和改法
如果 DNS 服务器暂时修不好,或者你只是想快速恢复工作,可以把域名直接写进 hosts 文件,让系统跳过 DNS 查询。
Linux/macOS 路径是/etc/hosts,Windows 是C:\Windows\System32\drivers\etc\hosts。加一行:
203.0.113.10 git.example.com保存后立刻生效,不需要重启网络。再执行ping git.example.com或者git ls-remote,理论上已经能走 IP 直连。
5.2 临时方案背后的两个坑
坑一:IP 会变。很多公共仓库放在 CDN 或负载均衡后面,IP 地址随时可能调整。你今天写入 hosts 的 IP 明天可能就失效,而且手动维护 hosts 容易忘,坏了你还不一定想得到是 hosts 的问题。所以 hosts 方案只能当“止血”手段,问题解决后建议删掉。
坑二:IP 直连和证书不匹配。如果目标仓库启用了严格 HTTPS,你直接写 IP 访问,TLS 证书里证的是域名而不是 IP,Git 会报证书校验失败。有人为了省事把证书校验关掉,我明确不建议这么干,这等于把 Git 的安全防线降到了裸奔级别,一旦连接的是伪造服务器,你的代码和凭据都有风险。
5.3 什么时候适合长线使用 hosts
也不是说 hosts 方案百无一是。若你的 Git 服务器是公司内网固定 IP,域名基本不变,那么在 hosts 里维护一份映射非常合理。我见过不少公司内部 Git 服务就是这种模式:域名解析服务不稳定,但服务器 IP 几十年不变,写 hosts 反而更省事。关键是判断你的场景属于“基础设施不稳定”还是“临时应急”,前者可以用 hosts,后者应该优先把 DNS 配好。
6. 第五步:本地解析服务、缓存和 IPv6 的“暗中作祟”
6.1 本地 DNS 缓存进程需要兜底
很多排查做到第四步就结束了,但现实里还有一些“隐藏关卡”。最常见的变数来自本机缓存服务。Linux 上如果装了nscd、dnsmasq或者systemd-resolved,它们会在系统层面缓存 DNS 结果。即使你改了 DNS 服务器,缓存里的旧记录仍然会顶一段时间。
处理方式就是重启对应的服务:
sudo systemctl restart systemd-resolved sudo systemctl restart nscd sudo systemctl restart dnsmasqWindows 上用ipconfig /flushdns清 DNS 缓存,原理一样。macOS 的解析缓存相对独立,用之前给过的那条命令刷新。
6.2 多网卡和路由优先级问题
笔记本上同时开着有线、无线或者虚拟网卡时,DNS 解析结果可能来自不同的网络接口。系统会选择优先级最高的那个接口作为 DNS 通道,有时候你明明改的是有线网卡的 DNS,系统实际查的还是无线网卡的 DNS。
排查时可以看路由表:
ip route重点观察default那一条走向哪个网卡。如果发现默认路由指向了你没在用的虚拟网卡,就需要调路由优先级,或者干脆临时禁用多余网卡:
sudo ip link set down 虚拟网卡名这一步直接验证是不是网卡间“打架”造成的问题。
6.3 IPv6 优先策略把解析结果带沟里
Could not resolve host报错不一定意味着域名完全没解析出 IP。如果 DNS 返回了 IPv6 地址(AAAA 记录),但当前网络根本不通 IPv6,而系统又优先尝试 IPv6,那表现出来的现象就可能是连接超时,偶尔也会以 “cannot resolve” 之类的形式收场。用下面的命令排查:
curl -6 -v https://git.example.com curl -4 -v https://git.example.com如果-4能通而-6不通,可以在 Git 层面强制使用 IPv4:
git config --global http.version HTTP/1.1不过真正稳妥的办法还是调整系统的 IPv6/IPv4 优先级,把 IPv4 往前放。Linux 上可以通过修改/etc/gai.conf,取消precedence ::ffff:0:0/96 100这一行的注释,让 IPv4 映射地址优先。
7. 实战排障速查:症状、原因与解法对照
整理一个速查表,遇到这类问题直接照着找答案:
| 症状 | 最常见原因 | 快速解法 |
|---|---|---|
| 所有域名都解析失败 | 本机 DNS 配置为空或失效 | 配公共 DNS,刷新缓存 |
只有git.example.com解析失败 | 域名拼写错误、服务器域名配置变化 | 检查 URL,nslookup确认 |
| 昨天正常今天突然失败 | 网络环境切换、DNS 缓存脏数据 | ipconfig /flushdns,重启网络 |
| 全团队同时失败 | 公司 DNS 服务器故障或策略调整 | 联系网络管理员,临时用 hosts |
| 换网络后失败 | 手动固定 DNS 和当前环境不匹配 | 改回自动获取 DNS |
| 有 IP 但连接超时 | IPv6 优先、防火墙拦截、CDN 节点变化 | curl 分别测 v4/v6,查路由 |
git clone能用curl失败 | 代理或本地安全软件拦截 | 检查本地安全软件、Git 配置 |
顺带补充一个 Git 层面的小检查项。修改完网络和 DNS 之后,有些老项目的 remote URL 还停留在旧域名上,虽然网络恢复正常,但仓库地址本身已经失效。先执行git remote -v看一眼当前 remote,确认确实是你想访问的地址,必要时用:
git remote set-url origin https://git.example.com/group/project.git修正 URL。
8. 最后分享一次真实定位过程
最后讲个我印象很深的案例。某团队新来的A同学提交代码时一直报域名解析失败,办公网和家里都失败,但组里其他人完全正常。我按上面的步骤走:ping网关通,ping公网IP通,nslookup git.example.com报错。看/etc/resolv.conf发现里面只有一个 DNS,写的是早已不存在的旧内网地址。机器之前是在另一个环境配的,网络换了好几次,这个固定 DNS 一直没人清理,导致所有域名都解析不了。
改回自动获取 DNS,刷新缓存,一条命令恢复。整个过程不到十分钟,关键就是没有在“账号密码”“网络断线”这些方向上空转。域名解析失败本身不可怕,可怕的是拿到报错后乱试。按上面这套流程一步步走,绝大多数问题都能在5步内找到病根。以后你的 Git 再飘红,先冷静看一眼报错,再决定要不要从鞋底开始修起。