← Back to blogGuides

Should I Add an AAAA Record? IPv6 DNS Without Breaking Things

Add an AAAA record only if the service works over IPv6 end to end. Happy Eyeballs, a pre-flight checklist, broken-IPv6 symptoms, and mail and PTR on IPv6.

Published: · 7 min read

Add an AAAA record if, and only if, the service behind the name really works over IPv6 from end to end: address, listener, firewall, TLS, application. A correct AAAA record makes your site reachable for IPv6-only and IPv6-preferring networks. A wrong AAAA record is worse than none, because it sends part of your visitors to an address that does not answer, and the failures look random. A missing AAAA record is not an error; the name is simply IPv4-only, and everything keeps working.

What an AAAA record is

An AAAA record (RFC 3596, pronounced "quad-A") maps a hostname to a 128-bit IPv6 address, exactly as an A record maps it to an IPv4 address. A dual-stack host publishes both:

www.example.com.   300   IN   A      192.0.2.10
www.example.com.   300   IN   AAAA   2001:db8:10::10

The two records are independent. Nothing keeps them in sync: they can point to different machines, and one can be updated while the other is forgotten. Much of this guide follows from that.

$ dig +short AAAA example.com
2001:db8:10::10

How clients choose: Happy Eyeballs

A dual-stack client asks for both A and AAAA. If it gets both, it prefers IPv6. What happens when the IPv6 address does not answer depends on the client.

Browsers and modern operating system libraries implement Happy Eyeballs (RFC 8305): they start the IPv6 connection first and, if it has not completed after a short delay (the RFC recommends 250 ms), start an IPv4 attempt in parallel and use whichever connects first. The visitor notices nothing.

That is why a broken AAAA can survive for months: browsers mask it. Many other clients do not:

  • scripts and command-line tools, API clients and webhooks from other services;
  • older HTTP libraries and language runtimes;
  • monitoring probes;
  • some mail software.

These try the IPv6 address and wait for the full connect timeout, often tens of seconds, before trying IPv4, or fail outright. So the typical symptom is: "the site is fine in the browser, but the payment provider's callback times out."

Before you add the record: a checklist

  1. The server has a global IPv6 address. ip -6 addr show scope global must show one; an address starting with fe80: is link-local and does not count. Prefer a static address over an automatically generated one that may change.
  2. The service listens on IPv6. In ss -tlnp, look for [::]:443 or *:443, not only 0.0.0.0:443. Check every port you serve: 80, 443, and anything else behind the same name.
  3. The firewall rules are mirrored for IPv6. IPv4 and IPv6 often have separate rule sets, and the cloud provider's security group needs IPv6 entries too. Do not block ICMPv6 wholesale: IPv6 needs it for neighbour discovery and for path MTU discovery, and dropping it produces connections that open and then stall.
  4. The right site answers on IPv6. The TLS virtual host must be configured for the v6 listener, or visitors get the default site and a certificate for a different name.
  5. The application understands IPv6 addresses. Log parsers, rate limiters, allowlists, geo rules, fraud checks and database columns sized for 255.255.255.255 all need a look. An IP allowlist for the admin area that has no IPv6 entries will lock out the administrator who is on an IPv6 network.
  6. Monitoring covers both families. A check that only uses IPv4 will stay green while IPv6 is down.
  7. Start with a low TTL such as 300 seconds, so that you can remove the record quickly. Raise it after a few quiet days. What TTL means in DNS explains why the old value is the one that matters.

Then test each family separately, which is the only way to see what a browser would hide:

$ curl -6 -sI https://example.com
HTTP/2 200
$ curl -4 -sI https://example.com
HTTP/2 200
$ ping -6 example.com        # ping6 on older systems

Both curl calls should return the same status and the same site. Run them from a machine outside your own network; if your workstation has no IPv6, a server elsewhere will do.

Behind a CDN or proxy

If the name is a CNAME to a CDN or a proxying platform, IPv6 is handled at the edge: the provider's target hostname publishes the AAAA records, visitors connect to the edge over IPv6, and the edge talks to your origin over whatever the origin supports, including IPv4 only. You do not add an AAAA record yourself; you cannot, since a CNAME excludes other records at the same name. This is the easiest way to serve IPv6 visitors from an IPv4-only origin. What still applies: your application sees visitor IPv6 addresses in the forwarded-address header, so item 5 of the checklist stays relevant.

Classic failure modes

Symptom Likely cause Check
After a server move, some visitors still reach the old site; it looks like propagation that never finishes The A record was updated, the old AAAA record was forgotten dig +short AAAA example.com; compare with the new server's address
Fine in browsers; scripts, webhooks or monitoring time out AAAA points to an address where a firewall silently drops packets curl -6 -sI https://example.com from outside
Certificate warning or wrong site for some visitors only No matching virtual host on the IPv6 listener curl -6 -sv https://example.com and read the certificate subject
Certificate renewal fails although the site works The ACME validator may connect over IPv6 when an AAAA record exists, and reaches a broken or different server curl -6 -sI http://example.com/.well-known/acme-challenge/test
Large pages hang over IPv6, small ones load ICMPv6 is blocked, so path MTU discovery fails firewall rules for ICMPv6 "packet too big"
Admin area or API rejects legitimate users Allowlist or rate limiter knows IPv4 only application logs for IPv6 client addresses
Outbound mail is rejected by large providers The server sends over IPv6 without PTR or SPF coverage next section

The first row deserves emphasis. When you migrate, put AAAA on the same checklist as A, as described in changing nameservers without downtime. If the new server has no IPv6, delete the AAAA record rather than leaving it.

Mail on IPv6

Mail is where IPv6 mistakes cost the most. A mail server that has a global IPv6 address will often use it for outbound connections whenever the receiving side publishes AAAA records for its MX hosts, whether you planned for that or not. Large receivers tend to be strict with IPv6 senders. For the IPv6 address you need:

  • a PTR record, set by whoever provides the address, as covered in reverse DNS and PTR records;
  • a matching AAAA record for the hostname the PTR names, so that forward and reverse agree;
  • the address or prefix in your SPF record with the ip6: mechanism.
$ dig +short -x 2001:db8:10::25
mail.example.com.
$ dig +short AAAA mail.example.com
2001:db8:10::25
$ dig +short TXT example.com
"v=spf1 ip4:192.0.2.25 ip6:2001:db8:10::25 -all"

If you cannot get a PTR record for the IPv6 address, configure the mail server to send over IPv4 only. That is a legitimate and common choice; receiving mail over IPv6 can stay enabled.

Common mistakes

  • Adding AAAA because a checklist or a scanner marked its absence as a problem, without testing IPv6 connectivity first.
  • Testing only in a browser. Happy Eyeballs will tell you everything is fine.
  • Copying the address from the server without checking whether it is global, static and routed.
  • Leaving the AAAA of a previous hosting provider in the zone after a move.
  • Mirroring none of the IPv4 firewall rules, in either direction: a closed web port, or a database port that is open to the world over IPv6 only.
  • Blocking all ICMPv6 out of IPv4 habit.
  • Forgetting ip6: in SPF and the PTR for the mail server's IPv6 address.
  • Publishing AAAA for www but not for the apex (or the reverse) and then debugging redirects that behave differently per network.

Check it with OrbitProbe

The OrbitProbe DNS lookup shows the A and AAAA records of a hostname side by side, with their TTLs, as public resolvers return them at that moment. Run it after every server move: an AAAA record you did not expect, or one that still carries the previous provider's prefix, is the forgotten record from the table above. Run it for the apex, for www and for the mail hostname separately, since each name has its own records. An overview of all record types is in DNS record types explained.