你在给新域名配 DNS。Vercel 文档说”加 A 记录”,YouTube 教程说”用 CNAME”。你在 apex(裸根域,example.com)上试了 CNAME,结果 DNS 提供商要么直接拒绝,要么接受了之后 MX 邮件就投递不了了。
最快修复:apex 用 A 记录(如果提供商有 ALIAS/ANAME 或 CNAME flattening 选项也可以用);子域(比如 www)用 CNAME。所有这些背后只有一条硬规则,来自 RFC 1912 §2.4:CNAME 在同一个 name 上不能跟任何其它记录共存。 apex 上一定带着别的记录(SOA、NS,通常还有 MX),所以在那儿放 CNAME 是非法的,会把这些记录顶掉;子域上一般没别的记录,所以用 CNAME 没问题。拿不准时,以你主机平台后台显示的值为准,别信通用教程。
先判断你属于哪一类
| 你的情况 | 该用什么 |
|---|---|
apex / 根域(example.com、@) | A 记录指向平台 IP。只有需要跟踪会轮换的目标时才用 ALIAS/ANAME 或 Cloudflare CNAME flattening。 |
www 或其它子域 | CNAME 指向平台目标(*.vercel-dns.com / *.netlify.app / *.pages.dev / username.github.io)。 |
| 提供商报错 “CNAME at apex” | apex 改成 A(或 ALIAS)。 |
| 加完记录后邮件断了 | 你在 apex 放了 CNAME,把 MX 顶掉了。换成 A。 |
| 站点时而旧时而新 | 同一个 name 上同时有 A 和 CNAME(或旧 + 新)。删掉错的那条。 |
常见原因
按命中率从高到低排。
1. 在 apex 用了 CNAME
RFC 1912 §2.4 禁止在 zone apex 用 CNAME,因为 apex 必须持有 SOA 和 NS(通常还有 MX),而 CNAME 不能跟任何其它记录共用一个 name。提供商会报类似 CNAME records cannot coexist、CNAME conflicts with NS 的错,或者静默接受、然后邮件就发不出去了。
怎么判断:DNS 提供商错误里提到 “CNAME and apex”、“CNAME flattening required”,或者根上有 CNAME 且 MX 记录突然解析不出来。
2. 跟了两套文档
一套说用 A、一套说 CNAME,你同一个 name 两个都配了。提供商可能拒绝第二条,也可能静默接受导致解析结果不可预测。
怎么判断:DNS 面板里同一个 name 有两条记录。应该只留一种,绝不能两条都在。
3. 该用 CNAME 时用了 A
子域上,像 Vercel(www)、Netlify 给你的 CNAME 目标会解析到负载均衡、会轮换的 IP。你硬编码一条 A 记录指向单个 IP,主机更换服务器那天,你就指向了一台过期的机器。
怎么判断:主机文档说 CNAME cname.vercel-dns-0.com 但你设了 A 76.x.x.x。今天正常,几周后莫名其妙就挂了。
4. 该用 A 时用了 CNAME
Vercel 的 apex 要求 A 76.76.21.21,不是 CNAME。某些平台接受 ALIAS/ANAME(或 CNAME flattening)作为 apex 上类 CNAME 的选项。如果你的 DNS 提供商没有这类选项,就只能用 A。
怎么判断:你的 DNS 提供商没有 apex CNAME 选项,你还是在 apex 设了 CNAME,然后平台拒发 SSL 证书,或显示 Invalid Configuration / DNS verification failed。
5. 迁移过程中混了记录
你换了主机。旧的 A 记录还在,新的 CNAME 指向别处。解析器在两者间轮询,或不一致地挑一个。
怎么判断:同一个 name 两条记录指向不同地方;站点时而加载新部署、时而加载旧的。
6. 用了 ANAME/ALIAS,但提供商底层把它实现成真 CNAME
ANAME 和 ALIAS 是非标准扩展,通过在查询时把目标解析成 A/AAAA 答复来模拟 apex CNAME 的行为。有些提供商实现得对;少数把 ANAME 底层映射成真正的 CNAME,于是又把 MX 破坏了。
怎么判断:看提供商关于 ANAME 兼容性的说明。加一条 MX 记录测试一下;如果它消失或报冲突,说明你的 ANAME 其实是 CNAME。
最短修复路径
第 1 步:查你主机平台的要求
下面是截至 2026 年 6 月的官方值。务必再对照你自己后台显示的值,因为有些平台会发给每个项目专属的目标。
| 平台 | Apex(@) | www / 子域 |
|---|---|---|
| Vercel | A 76.76.21.21(或把 nameserver 切到 Vercel) | CNAME cname.vercel-dns-0.com(或你后台显示的项目专属目标) |
| Netlify | A 75.2.60.5,或 ALIAS/ANAME 到 apex-loadbalancer.netlify.com | CNAME yoursite.netlify.app |
| Cloudflare Pages | Cloudflare nameserver;在 @ 上 CNAME yoursite.pages.dev(自动 flatten) | CNAME yoursite.pages.dev |
| Firebase Hosting | 控制台给出的两条 A 记录 | 控制台给出的 CNAME |
| GitHub Pages | A 185.199.108.153、185.199.109.153、185.199.110.153、185.199.111.153 | CNAME username.github.io |
| AWS(S3 + CloudFront) | A-ALIAS 到 CloudFront 分发(Route 53) | CNAME 到 CloudFront 域名 |
照平台文档或后台的精确值用。
第 2 步:apex 用 A 或 ALIAS/ANAME(或干脆切 nameserver)
如果你的 DNS 提供商支持 ALIAS/ANAME(Route 53、Cloudflare、DNS Made Easy、Namecheap、Porkbun),就可以在 apex 用它来跟随一个类 CNAME 的目标。否则用 A 记录 + 平台 IP。
- Cloudflare:直接在
@上放一条CNAME就行。只要记录 name 是@,Cloudflare 在所有套餐(含 Free)上都会自动做 CNAME flattening——把链条解析到A/AAAA再返回,既符合 RFC、MX又照常工作。 - Vercel / Netlify / Firebase:最干净的做法是把整个域名委派给平台的 nameserver,之后平台会替你管理 apex 的
A记录。如果你坚持用外部 DNS,就用上面表里的A值。
第 3 步:子域用 CNAME
www、blog.yourdomain.com、staging.yourdomain.com 都应该用 CNAME 指向平台目标。绝不要在主机做负载均衡的子域上,用 A 记录硬塞一个 apex IP。
第 4 步:删掉冲突记录
同一个 name 上不要 A 和 CNAME 都留,也别留着上一个主机的过期记录。每个 name 只留一条,其余删掉。
第 5 步:用 dig 验证记录类型
dig +short example.com # apex:应打印一个 IP(A 记录)
dig +short www.example.com CNAME # www:应打印 CNAME 目标
如果 apex 打印出来的是主机名而不是 IP,说明那儿还留着 CNAME。如果 www 的 CNAME 查询什么都没打印,说明你在该放 CNAME 的地方设了 A。再确认邮件没被波及:
dig +short MX example.com # 应仍列出你的邮件主机
第 6 步:等传播后再验证一次
DNS 改动不是即时生效。要给缓存清理留出最多 24 小时(有些提供商提示最多 48 小时),不过大多数解析器会在 15-60 分钟内更新。从几个公共解析器查一查,再刷新浏览器:
dig +short example.com @1.1.1.1 # Cloudflare 解析器
dig +short example.com @8.8.8.8 # Google 解析器
当所有解析器都返回新值、平台显示域名为 Valid Configuration(且 SSL 证书签发成功)时,就搞定了。
怎么确认已经修好
满足下面三条就算彻底修好:
dig +short example.com返回平台 IP(一条A),dig +short www.example.com CNAME返回平台主机名(一条CNAME)。dig +short MX example.com仍列出你的邮件主机,说明邮件没断。- 主机后台显示域名有效,并以 HTTPS 提供服务、没有证书报错。
常见问答
根域到底能不能用 CNAME?
真正的 CNAME 不行。变通方案是 ALIAS/ANAME 或 Cloudflare 的自动 CNAME flattening——它们对外像 CNAME 目标,但实际返回 A/AAAA 记录,所以 apex 上的 SOA、NS、MX 照常工作。
我在根域加了 CNAME 之后邮件为什么停了?
CNAME 不能跟同名的任何其它记录共存(RFC 1912 §2.4),所以它把 apex 的 MX 记录顶掉了。把 apex 的 CNAME 换成 A 记录(或 ALIAS/flattening),MX 记录就又可见了。
A 记录和 CNAME 到底有什么区别?
A 记录把一个 name 直接映射到一个 IPv4 地址(IPv6 用 AAAA)。CNAME 是别名,意思是”去查另一个 name”,解析器再去取那个 name 的 A/AAAA。A 钉死在某个 IP 上;CNAME 跟随目标当前解析到的结果。
我该用 A 记录,还是把 nameserver 切到主机?
如果你只在这个平台上托管网站、不跑复杂的外部 DNS,委派 nameserver 最省心,因为平台会替你更新 apex 的 IP。如果你需要在别处管理 MX、TXT 等记录,就保留外部 DNS、用 A 记录。
主机给的是 cname.vercel-dns-0.com 而不是 cname.vercel-dns.com,哪个对? 以你自己后台显示的值为准。Vercel 会发给每个项目专属的 CNAME 目标,后缀在不同项目间可能不一样;从后台复制那个值永远是对的。
dig 输出看着没问题,但浏览器还是显示旧站点,为什么?
是你本地的 DNS 缓存或浏览器还留着旧答复。清一下操作系统的解析缓存,用 dig +short example.com @1.1.1.1 查公共解析器,等公共解析器返回新值后,再开一个无痕窗口试试。
预防建议
- 信你主机提供商后台显示的值,不要信通用教程。
- 每个 name 选了哪种记录类型,在 DNS 提供商的备注字段里记下来。
- apex 域名:永远用
A或ALIAS/ANAME/flattening,永远不用真正的CNAME。 - 同名不要混类型;选一条、删冲突。
- 换主机时,先彻底删掉旧记录,再加新的。
相关阅读
- DNS A vs CNAME 解释
- 域名指向了错的托管商
- 根域名 vs www 混乱
- 同一域名在 Vercel 工作但 Firebase 不行
- 域名连接后站点时而能开时而不能:4 个原因 + 对症修复
- 浏览器 SSL Mixed Content 警告
- MX 记录被覆盖——邮件断了
- RSS / OG URL 仍是占位域名
- 证书被拒:Certificate Transparency 日志不匹配 —— 排查指南
- Cloudflare 橙云灰云搞反,站点立刻挂 —— 排查与修复
- 开启 DNSSEC 后 SERVFAIL:信任链断了 —— 排查与修复
- HSTS preload 进了就出不来:站点被锁死在 HTTPS
- IPv6 用户打不开站点:AAAA 记录缺失或挂了 —— 完整排查
- 子域 NS 委派挂了:缺 Glue 记录 —— 排查与修复
- 证书续签自动化静默挂了,站点现在不受信任 —— 完整修复指南