Ch. 20 · Networking

Networking: DNS Record Types

Read real dig output for A, AAAA, CNAME, MX, TXT, NS, SOA and CAA records, and learn which combinations DNS rejects and why.

~6 min readbeginnerupdated Oct 19, 2026

Ask dig about a domain and it prints lines that all look alike: a name, a number, IN, a type, and some data. The type is what changes the meaning of everything to its right. Once you can read each type, most “the site is down” or “our email goes to spam” tickets become a matter of looking at the right record.

All the output below came from querying Cloudflare’s public resolver (dig @1.1.1.1 ...) against real domains. Your TTLs will differ because they count down in the resolver’s cache.

Reading one line of dig output

$ dig @1.1.1.1 example.com A +noall +answer
example.com.		95	IN	A	104.20.23.154
example.com.		95	IN	A	172.66.147.243
Terminal

From left to right: the owner name (with a trailing dot, meaning it’s fully qualified), the remaining TTL in seconds, the class (IN for internet, and it’s essentially always that), the record type, and the record data. Two A lines at the same name form a record set. Clients get both and usually try them in the order received, and resolvers often rotate that order, which gives you crude load spreading for free.

+noall +answer trims dig’s output to just the answer section. When you need to see why something failed, drop those flags and read the status: field in the header (NOERROR, NXDOMAIN, SERVFAIL).

Address records: A and AAAA

A holds one IPv4 address, AAAA one IPv6 address. They’re independent: having an A record doesn’t imply anything about IPv6.

$ dig @1.1.1.1 example.com AAAA +noall +answer
example.com.		58	IN	AAAA	2606:4700:90d5:72db:f239:0:ef6b:ff98
Terminal

Dual-stack clients ask for both and, with Happy Eyeballs, race the connections, preferring IPv6 when it works. A common outage pattern follows from that: someone publishes an AAAA record for a server whose IPv6 firewall rules were never opened. IPv4-only users are fine, IPv6 users see slow or failed connections, and the bug report says “it only breaks on mobile”. Publish AAAA only when the service actually answers on that address.

Aliases: CNAME and its two rules

A CNAME says “this name is another name; go look that one up instead”. GitHub uses one for www:

$ dig @1.1.1.1 www.github.com A +noall +answer
www.github.com.		2612	IN	CNAME	github.com.
github.com.		20	IN	A	20.207.73.82
Terminal

You asked for A, and the resolver returned the alias plus the target’s A record. Notice the TTLs are different: each record in the chain is cached on its own schedule. The alias here changes rarely, while the address behind it has a short TTL.

Two rules trip people up, and interviewers ask about both.

A CNAME must be alone at its name. If shop.example.com is a CNAME, it can’t also have an MX, TXT or anything else (DNSSEC records excepted). The reason is logical: a CNAME means “everything about this name lives over there”, so local records at the same name would contradict it. Most DNS dashboards refuse to save the combination; some older ones accept it and resolvers then behave inconsistently.

So the zone apex can’t be a CNAME. The apex (example.com itself) always carries an SOA and NS records, which the zone needs to exist. A CNAME there would break rule one. That’s why you can point www.example.com at myapp.herokuapp.com with a CNAME but not example.com. Providers work around this with non-standard types called ALIAS, ANAME or “CNAME flattening”: the provider resolves the target itself and serves plain A/AAAA records at the apex. To resolvers it’s just addresses.

Mail records: MX and the TXT records around it

$ dig @1.1.1.1 gmail.com MX +noall +answer
gmail.com.		1848	IN	MX	40 alt4.gmail-smtp-in.l.google.com.
gmail.com.		1848	IN	MX	10 alt1.gmail-smtp-in.l.google.com.
gmail.com.		1848	IN	MX	5 gmail-smtp-in.l.google.com.
gmail.com.		1848	IN	MX	20 alt2.gmail-smtp-in.l.google.com.
gmail.com.		1848	IN	MX	30 alt3.gmail-smtp-in.l.google.com.
Terminal

The number before each host is the preference, and lower wins. A sending server tries gmail-smtp-in (5) first and moves up the list only if that fails. The order in which the lines arrive is irrelevant. Two mistakes show up here: putting an IP address in the MX data (the field must be a host name with its own A/AAAA), and pointing MX at a name that’s a CNAME, which RFC 2181 forbids and some mail servers reject.

Mail delivery and spam filtering also lean on TXT records, which hold arbitrary strings:

$ dig @1.1.1.1 example.com TXT +noall +answer
example.com.		300	IN	TXT	"v=spf1 -all"
example.com.		300	IN	TXT	"_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9"

$ dig @1.1.1.1 _dmarc.github.com TXT +noall +answer
_dmarc.github.com.	300	IN	TXT	"v=DMARC1; p=quarantine; sp=reject; pct=100; rua=mailto:dmarc@github.com; ruf=mailto:dmarc@github.com; fo=1"
Terminal

v=spf1 -all is an SPF policy that says “no server is allowed to send mail for this domain”, a sensible setting for a domain that never sends email. The second string is the kind of token a service asks you to publish to prove you control the domain. DMARC lives at the special name _dmarc.<domain> and tells receivers what to do with mail that fails SPF and DKIM checks. A frequent mistake is adding a second v=spf1 record when signing up for a new email vendor. SPF allows exactly one per name; with two, receivers return a permerror and the policy is effectively ignored. You merge the include: entries into a single record instead.

Records about the zone and its certificates

NS names the authoritative servers, and SOA describes the zone itself: the primary server, an administrator mailbox written with a dot instead of @, a serial number, timers for secondary servers, and the negative-caching TTL in the final field.

$ dig @1.1.1.1 example.com NS +noall +answer
example.com.		74180	IN	NS	hera.ns.cloudflare.com.
example.com.		74180	IN	NS	elliott.ns.cloudflare.com.

$ dig @1.1.1.1 example.com SOA +noall +answer
example.com.		1800	IN	SOA	elliott.ns.cloudflare.com. dns.cloudflare.com. 2416374680 10000 2400 604800 1800
Terminal

CAA limits which certificate authorities may issue for the domain. GitHub allows four:

$ dig @1.1.1.1 github.com CAA +noall +answer
github.com.		3600	IN	CAA	0 issue "digicert.com"
github.com.		3600	IN	CAA	0 issue "letsencrypt.org"
github.com.		3600	IN	CAA	0 issuewild "letsencrypt.org"
...
Terminal

If you add a CAA record listing only one CA and later switch providers, renewals fail with a CAA error until you update it. It’s an easy one to forget during a migration.

A few others you’ll meet: PTR maps an address back to a name under in-addr.arpa (dig -x 8.8.8.8 returns dns.google.), and mail servers check that your sending IP has one. SRV publishes host and port for a service, as in _xmpp-server._tcp.jabber.org. 60 IN SRV 30 30 5269 scarlet.jabber.org. (priority, weight, port, target). The newer HTTPS record advertises protocol support such as HTTP/3 before the first connection; older dig builds show it as TYPE65 with hex data.

Practice question: setting up a new domain

You’re launching acme-tools.com. The app runs behind a hosted platform at acme.platform-apps.net, mail goes through a provider whose servers are mx1.mailhost.net and mx2.mailhost.net, the marketing tool needs to send mail as your domain, and you use Let’s Encrypt. List the records you’d create and one mistake each one invites.

Answer

  • www → CNAME acme.platform-apps.net. Fine, because www has no other records. Don’t add a TXT at www later.
  • Apex → ALIAS/flattened record to the same target, or the platform’s static A and AAAA addresses. A literal CNAME at the apex would collide with the SOA and NS records.
  • MX 10 mx1.mailhost.net. and MX 20 mx2.mailhost.net. Lower preference is tried first; the targets must be host names with address records, not IPs or CNAMEs.
  • One TXT "v=spf1 include:<mail provider> include:<marketing tool> -all". Both senders go in one record; two SPF records cause a permerror.
  • TXT at _dmarc starting with p=none while you read the reports, then tightening. Jumping straight to p=reject can drop legitimate mail from a sender you forgot.
  • CAA 0 issue "letsencrypt.org". Update it before you ever change CA, or renewal stops working.

The reasoning an interviewer wants is the “why” behind each one, especially the apex rule, since it’s the question most candidates guess at.

Keep going

More in Networking

read ✓Networking · mid

Networking: DNS Caching and TTL

See how resolvers count TTLs down, why NXDOMAIN answers are cached too, and how to schedule a DNS cutover so stale answers expire.

~7 min readread →
read ✓Networking · easy

DNS Resolution and Cached Answers

Follow one DNS lookup from your laptop to the authoritative server with dig, and see why two users can get different answers after a move.

~6 min readread →
read ✓Networking · hard

Network Debugging Along the Request Path

Find the first failing step in a request (DNS, TCP, TLS, HTTP or the app) with curl timings, dig, nc and openssl, using six real failures.

~6 min readread →
esc