Fixing CNAME Loop Errors on Static Hosts
How CNAME loops happen on Vercel, Netlify, and similar platforms, and how to break them without downtime.
What Is a CNAME Loop?
A CNAME loop occurs when DNS resolution enters an infinite chain of aliases. This can happen in two ways. The first is a direct or indirect circular reference: CNAME record A points to B, and B points back to A, or a longer chain like A points to B, B points to C, and C points to A. The second is a conflict between a CNAME record and other record types at the same DNS name, which causes some resolvers to fail or behave unpredictably.
When a resolver encounters a CNAME loop, it detects the circular reference after a limited number of follow-redirects (typically 8 to 16 hops) and returns an SERVFAIL or NXDOMAIN response. The result is the same: your domain stops resolving entirely.
RFC 2181, Section 10.1: "A CNAME record is not allowed to coexist with any other record type at the same owner name." This is not a platform quirk—it is a fundamental DNS specification. If you have a CNAME for www.example.com, you cannot also have an A, AAAA, MX, or TXT record for www.example.com.
How CNAME Loops Happen on Vercel, Netlify, and GitHub Pages
Static hosting platforms encourage you to point your domain to their infrastructure using a CNAME record. Vercel provides cname.vercel-dns.com, Netlify provides your-site.netlify.app, and GitHub Pages provides your-org.github.io. These are all CNAME targets.
The problem arises when a developer configures their DNS incorrectly in one of these ways:
- CNAME on the apex domain: The apex (
example.com) cannot use a CNAME per DNS standards. Some providers offer CNAME flattening (ALIAS/ANAME records) but not all. If you create a standard CNAME for the apex, most resolvers will ignore it or fail. - CNAME plus A record on the same name: You set a CNAME pointing to Vercel, but also keep an old A record pointing to your previous host. The CNAME prohibits any other record type at that name, causing a conflict.
- Proxy/CDN CNAME pointing back to the same domain: You enable Cloudflare proxy on a CNAME record that points your domain back to itself (e.g.,
www.example.com CNAME example.com), creating a loop. - Platform redirect loops: Vercel redirects
example.comtowww.example.com, while GitHub Pages redirectswww.example.comback toexample.com. The DNS resolves fine, but HTTP requests bounce endlessly.
Example Scenario: CNAME + A Record Conflict
Imagine you are migrating app.yourname.is-pro.dev from a VPS to Vercel. Your DNS currently has:
app.yourname.is-pro.dev. A 203.0.113.10
app.yourname.is-pro.dev. AAAA 2001:db8::1
You add a new CNAME record pointing to Vercel but forget to remove the existing A and AAAA records:
app.yourname.is-pro.dev. A 203.0.113.10 (old, still present!)
app.yourname.is-pro.dev. AAAA 2001:db8::1 (old, still present!)
app.yourname.is-pro.dev. CNAME your-site.vercel.app.
This configuration violates RFC 2181. Different resolvers handle this differently:
- Some resolvers will return the A records and ignore the CNAME entirely, so traffic still goes to your old VPS.
- Some resolvers will return an error (
SERVFAIL), making your app unreachable. - Some resolvers will follow the CNAME but also return the A records, causing unpredictable behavior.
The fix is simple: remove all A and AAAA records before adding a CNAME, or use a CNAME-only configuration.
Why CNAME + Other Record Types Conflict
RFC 2181 is explicit: "If a CNAME RR is present at a node, no other data should be present." The rationale is that a CNAME is not just a record—it is an alias that tells the resolver "this name is an alias for another name." If the resolver also finds an A record at the same node, it does not know which to trust. Is the address the one from the A record, or should the resolver follow the alias and use the A record from the target?
This ambiguity is resolved by the RFC's prohibition: CNAME wins, and everything else at that name is ignored or causes an error. The practical effect is that you cannot host any other service (email, FTP, etc.) on a hostname that is a CNAME alias. If you need mail.example.com to be a CNAME, you cannot also have an MX record for it.
Step-by-Step Debugging
1. Check for CNAME Records
Query the specific CNAME record for your domain:
dig yourname.is-pro.dev CNAME +short
If this returns a target like your-site.vercel.app., you have a CNAME configured. If it returns nothing, you do not have a CNAME at that name.
2. Check for Conflicting A/AAAA Records
Query A and AAAA records at the same name:
dig yourname.is-pro.dev A +short
dig yourname.is-pro.dev AAAA +short
If you have both a CNAME and an A record for the same name, you have a conflict. Remove the A/AAAA records if you want the CNAME to work.
3. Check for MX or TXT Records at the CNAME Name
Query other record types that should not coexist with a CNAME:
dig yourname.is-pro.dev MX +short
dig yourname.is-pro.dev TXT +short
If you see MX or TXT records alongside a CNAME, remove them or move them to a different subdomain.
4. Verify the CNAME Target Resolves
The target of your CNAME must itself resolve. If you CNAME to your-site.vercel.app, verify that target is reachable:
dig your-site.vercel.app A +short
If the target returns no A records, your CNAME resolves to nowhere, and your domain will not load.
5. Trace the Full Resolution Chain
Use dig +trace to see every step of DNS resolution:
dig yourname.is-pro.dev +trace
This shows each nameserver queried and the response received. Look for repeated CNAME references or unexpected aliases.
6. Check for Application-Level Redirect Loops
Even if DNS is correct, your hosting platform may create HTTP-level redirect loops. Test with curl:
curl -IL https://yourname.is-pro.dev
Inspect the redirect chain. If you see Location: https://www.yourname.is-pro.dev followed by Location: https://yourname.is-pro.dev, you have an application-level loop that must be fixed in your host's redirect settings.
Common Scenarios That Cause Loops
Using a CNAME on the Apex Domain
DNS standards do not allow CNAME records at the zone apex (the root domain like example.com). The apex must have NS, SOA, and usually A/AAAA records. If you need the apex to point to a hosting provider, use:
- CNAME flattening (ALIAS/ANAME): Supported by Cloudflare, DNSimple, and some other DNS providers. The provider resolves the target IP at the DNS level and returns an A record, so the apex appears to have a CNAME.
- Redirect by your hosting provider: Use a subdomain like
wwwwith a CNAME, and configure your hosting platform to redirect the apex to thewwwsubdomain.
Proxy/CDN Records That CNAME Back to the Same Domain
This scenario is subtle but common. You configure Cloudflare (or another reverse proxy) for www.example.com. Cloudflare's proxy looks up the origin IP by resolving your CNAME. If your CNAME points to example.com (the apex), and the apex has an A record pointing to Cloudflare's proxy IP, you create a loop: Cloudflare queries DNS, gets the CNAME, follows it to the apex, gets the A record pointing at Cloudflare, and connects back to itself.
Solution: ensure your CNAME target bypasses any proxy. Use the origin IP directly, or configure DNS-only (gray cloud) for the CNAME record and use proxy only on the A record that resolves the CNAME target.
Prevention Strategies
- Audit all records before changes: Before adding a CNAME, list every record at that hostname. Remove A, AAAA, MX, and TXT records that should not coexist with the CNAME.
- Use a subdomain for the CNAME: Keep CNAME records on subdomains like
www,app, orblog. Use ALIAS/ANAME for the apex if available, or use a redirect service. - Test with dig before configuring the host: Verify that your DNS resolves correctly before telling your hosting provider to look for the domain. This avoids cascading configuration errors.
- Document your DNS architecture: Maintain a clear map of which hostnames point where. If
wwwis a CNAME to Vercel andapiis an A record to your VPS, document this so future changes do not introduce conflicts. - Use monitoring: DNS monitoring services can alert you when resolution fails, which often indicates a CNAME loop or conflict.
Specific Platform Notes
Vercel
Vercel's custom domains expect a CNAME pointing to cname.vercel-dns.com. For apex domains, Vercel provides nameserver delegation (use their nameservers) or CNAME flattening via their DNS dashboard. If you get a "CNAME loop" error in Vercel's dashboard, check that you have no other records conflicting with the CNAME and that the domain is not already configured on another Vercel project.
Netlify
Netlify provides a target like your-site.netlify.app. Netlify's DNS panel shows warnings when conflicting records exist. For apex domains, Netlify recommends using their managed DNS or configuring an ALIAS record with your DNS provider. Netlify also supports _redirects and netlify.toml for application-level redirects, which can create redirect loops if misconfigured between the apex and www.
GitHub Pages
GitHub Pages uses your-org.github.io as the CNAME target. GitHub's documentation explicitly warns against using CNAME records for apex domains. For apex, use A records pointing to GitHub's Pages IP addresses (185.199.108.153, 185.199.109.153, 185.199.110.153, 185.199.111.153). GitHub Pages also reads a CNAME file in your repository root, which must match the domain you are configuring. Mismatches between the DNS CNAME record and the repository CNAME file cause redirect loops.
Quick Reference: CNAME Rules
CNAME + A= conflict. Remove the A record.CNAME + AAAA= conflict. Remove the AAAA record.CNAME + MX= conflict. Move MX to a different hostname.CNAME + TXT= conflict. Move TXT to a different hostname.CNAME at apex= not allowed by RFC. Use ALIAS/ANAME or redirect.CNAME to self= loop. Check CNAME target is different from source.CNAME + proxy (Cloudflare orange cloud)= careful: ensure the CNAME target resolves to a real origin, not back through the proxy.
Need hands-on help? See Guides for step-by-step setup playbooks, or join the Discord community.
Deployment scenario from operations
An app became unreachable after a hostname was configured with both CNAME and legacy A records, triggering resolver ambiguity.
Common mistakes
- Mixing CNAME with other record types on the same host.
- Creating indirect CNAME chains without tracing final target.
- Ignoring HTTP redirect loops after DNS appears fixed.
How to verify it works
- Query CNAME and A/AAAA records for conflicts.
- Run `dig +trace` to inspect full delegation chain.
- Use `curl -IL` to confirm no redirect loop remains.