How DNS resolution works
On this page
Every connection starts with a lookup. Before a browser can talk to www.example.com, something has to turn that name into an address like 203.0.113.10, and DNS (the Domain Name System) is how that happens [1]. It’s usually invisible, and it’s behind a surprising number of “it works on my machine” problems.
This primer is about the lookup itself, with every record type you’re likely to meet at the end as a reference.
Reading a domain name
A name like www.example.com reads most naturally right to left, because that’s the order DNS works through it. Each part between the dots is a label, and the labels form a tree with the root at the top [1]:
Reading www.example.com from the bottom up: www, then example, then com, then the root. Each dashed box is a zone, and the teal lines are where one zone hands off to the next.
- The root sits at the top of the tree, above every TLD. Its label is empty, zero characters long, and that’s why it shows up as nothing but a trailing dot: the full form of
www.example.comiswww.example.com., where the last dot separatescomfrom the root’s empty label [1]. The label is empty because there’s only one root and every name ends there, so it needs nothing to tell it apart. It has nothing to do with where the root servers are: a name never contains server addresses at any level, and resolvers find the root servers a different way, covered in why there’s a root below. A file path works the same way. In/usr/bin, the leading/is the root directory, which has no name of its own either. DNS just writes names in the other order, most specific first, sowww.example.com.read right to left is the path/com/example/www, and the root’s/becomes the trailing dot. comis a top-level domain (TLD), one level below the root.exampleis the second-level domain, the part someone registers and owns.wwwis a subdomain. The owner can make as many as they like (app,api,mail), and each one can point somewhere different.
Nobody runs the whole tree. It’s split into zones, each a connected piece of the tree run by one organization and answered by one set of name servers [1]. The dashed boxes are zones. The root zone only knows about the TLDs, the com zone only knows about the domains registered under it, and the example.com zone holds the actual records for example.com and everything under it (unless its owner splits a piece off into a zone of its own).
Handing part of the tree to someone else is called delegation. The parent zone keeps NS records (name server records) that say which servers answer for the child zone, and those records are the pointers across each zone boundary [1]. The com zone has NS records for example.com and very little else about it: no web server addresses, no mail servers. So a lookup has to hop from zone to zone, following NS records down the tree.
Why there’s a root
The server that does lookups on your behalf, a recursive resolver (more on it below), starts out knowing nothing about any domain. To look up a name it has never seen, it needs a fixed place to start, and that place has to lead to every name that exists. The root is that place. The root zone is mostly one list: every TLD, and the name servers that answer for each one [2]. There are 1,437 TLDs as of October 2026 [3], and new ones get added, so expecting every resolver in the world to keep its own up-to-date copy of all their servers wouldn’t work.
So the list lives in one zone, and every resolver only has to know where that zone is. Resolver software ships with a small file called the root hints, the names and addresses of the root servers, which is all it needs to get started [4]. RFC 1034 gives the same reason for starting from root servers when a resolver has nothing better: they “provide eventual access to all of the domain space” [1].
The root moves the list of TLDs into one zone, served by 12 organizations, so each resolver only needs to know where the root is. In practice resolvers rarely ask it at all, because the TLD referrals it hands out get cached.
Who’s involved
Two different jobs get called “DNS servers,” and mixing them up makes the rest confusing:
- A resolver asks questions on your behalf until it finds an answer. It doesn’t own any names.
- A name server answers questions about the names it’s responsible for. It doesn’t go looking for anything.
There are five players in a typical lookup:
| Who | Job |
|---|---|
| Stub resolver | The small piece of your operating system that apps ask. “Stub” means minimal: it can’t search on its own, and it only knows the address of a recursive resolver to hand every question to [1]. |
| Recursive resolver | Does all the legwork: asks the other servers, follows their pointers, caches what it learns. Run by your ISP, your company, your cloud provider, or a public service. |
| Root name servers | Know which name servers handle each TLD. There are 13 root server names, run by 12 organizations, served from about two thousand instances around the world [5]. |
| TLD name servers | Know which name servers are responsible for each domain under their TLD (every *.com, for example). |
| Authoritative name servers | Hold the actual records for a zone and give the real answer. Run by whoever hosts the domain’s DNS, like Route 53. |
Recursive describes what you get from the resolver, not how the lookup travels. You ask it once, and it does the whole job and hands back a final answer or an error, never a pointer to somewhere else [1]. The servers it asks work the other way. They answer only from what they already hold, which is either the answer or a referral to a server closer to it [1]. Nothing gets passed from one of them to the next.
Following one lookup
The first time a laptop looks up www.example.com, with nothing cached anywhere, the recursive resolver goes out three times:
Dashed arrows are referrals, solid teal arrows carry the answer. Every query starts at the recursive resolver.
- The browser asks the operating system (the stub resolver) for the address of
www.example.com. - The stub resolver asks the recursive resolver it’s configured to use. From here on, the recursive resolver does all the work.
- The recursive resolver asks three servers in turn. A root server doesn’t know the answer and replies with a referral, the NS records for
.com. A.comTLD server doesn’t know it either and refers the resolver toexample.com’s name servers. One of those is authoritative for the zone, so it has the record and answers:www.example.comis203.0.113.10. - The recursive resolver hands the answer back to the stub resolver, which hands it to the browser, and the browser connects to
203.0.113.10.
Two details trip people up:
- The root and TLD servers never go find the answer themselves. They point the recursive resolver to the next server to ask, and the recursive resolver makes every query itself. The root server never talks to the TLD server, and the TLD server never talks to the authoritative one.
- The answer doesn’t travel back through the chain. The recursive resolver already has it after the third query and gives it straight to your machine.
A directory helpline works the same way. You call the helpline and ask for the number of someone at Example Corp. The operator doesn’t know it, so they call a national directory, which says “I don’t have that, but call the business directory on this number.” The business directory says “I don’t have it either, but call Example Corp’s front desk on this number.” The front desk knows its own staff and gives the operator the number, and the operator passes it back to you. The helpline is the recursive resolver, the national directory is a root server, the business directory is the .com TLD server, and Example Corp’s front desk is the authoritative name server. The operator makes every call, and you only ever talk to the helpline.
Caching, TTLs, and “propagation”
That full walk is rare. Every answer comes with a TTL (time to live), in seconds, and the recursive resolver keeps the answer that long before asking again [6]. Referrals get cached too, so a busy resolver almost never needs the root servers, and usually not the TLD servers either. Your operating system and browser keep their own small caches on top of that.
Caching explains “DNS propagation.” When you change a record, the authoritative server has the new value immediately, but every resolver that cached the old value keeps using it until its TTL runs out. Nothing is propagating. Old copies are expiring.
Say www.example.com has a TTL of 3600 seconds (an hour) and you move it to a new address at 12:00. One resolver happened to look it up at 11:30:
| Time | TTL left at 3600 | TTL lowered to 300 the day before |
|---|---|---|
| The day before | Nothing changes. | You lower the TTL to 300. Copies cached under the old 3600-second TTL run out within the hour. |
| 11:30 | The resolver caches the old address until 12:30. | The resolver caches the old address until 11:35. |
| 12:00 | You change the record. The authoritative server gives the new address straight away. | Same. |
| 12:00 to 12:30 | The resolver keeps handing out the old address. | The 11:30 copy expired at 11:35. Any copy the resolver fetched again before 12:00 expires by 12:05. |
| Last moment anyone can get the old address | 13:00, from a resolver that cached it just before 12:00 | 12:05 |
That’s why the usual advice before moving a site is to lower the record’s TTL a day or so ahead, so the old copies expire quickly when you make the switch, and raise it again afterward. The lower TTL has to go in at least one old TTL early, because resolvers holding the old copy don’t see the change to the TTL either until their copy expires.
“This name doesn’t exist” gets cached too. If a resolver looks up a name before you’ve created it, it remembers the failure for as long as the last number in the zone’s SOA record says (or the SOA record’s own TTL, if that’s shorter), and keeps saying the name doesn’t exist even after you add it [7].
Which resolver your machine uses
The recursive resolver usually comes from your network’s settings, handed out along with your IP address. To see which one you’re using:
macOS / Linux
scutil --dns # macOS: the full resolver configuration
cat /etc/resolv.conf # Linux: the resolver your programs are told to use
resolvectl status # Linux with systemd-resolved: the real upstream resolvers
Windows (PowerShell)
Get-DnsClientServerAddress # DNS servers for each network interface
Get-DnsClientServerAddress lists the DNS server addresses for each network interface [8].
On many Linux systems /etc/resolv.conf lists only 127.0.0.53. That’s an address on the machine itself, where systemd-resolved runs a local caching stub resolver, so the file doesn’t tell you which resolver does the lookups [9]. resolvectl status shows the DNS servers in effect, globally and for each network link [10].
That configuration can include more than one resolver, and some only apply to certain domains. A machine on a VPN might send *.corp.example.com to the company’s resolver and everything else to the normal one. That’s split DNS, and it’s why a name can resolve with the VPN up and fail without it, or resolve to a different address depending on which resolver answered. It’s also step 7 in the checklist for reaching private resources.
Why scutil --dns lists so many resolvers
On a Mac at home, scutil --dns often prints seven or more numbered resolvers, which looks like far too many. Usually only the first does ordinary lookups. A shortened example:
resolver #1
nameserver[0] : 2001:db8::53
nameserver[1] : 192.0.2.53
if_index : 14 (en0)
reach : 0x00000002 (Reachable)
resolver #2
domain : local
options : mdns
reach : 0x00000000 (Not Reachable)
resolver #3
domain : 254.169.in-addr.arpa
options : mdns
resolver #4
domain : 8.e.f.ip6.arpa
options : mdns
... (#5 to #7 are 9.e.f, a.e.f, and b.e.f.ip6.arpa)
- Resolver #1 is the default. It has the server addresses from your network settings, often two IPv6 and two IPv4 so there’s a backup of each, and no
domainline. The manual page forscutilsays the first one listed is the default, and the ones after it that name adomainare only used for names in that domain [11]. - The rest send local names to multicast DNS.
options : mdnsmeans “don’t ask a server, ask the devices on this network directly,” which is multicast DNS (mDNS), the protocol behind finding printers and other computers by name [12]. They have no server addresses, soreachsays Not Reachable, and that’s expected. localcovers names likemy-printer.local, which mDNS owns [12].254.169.in-addr.arpacovers reverse lookups for link-local IPv4 addresses, the169.254/16range a device gives itself when nothing on the network hands it one [13]. Names for those addresses only mean something on the local network, so the mDNS standard sends their lookups there too [12].8.e.fthroughb.e.f.ip6.arpado the same for IPv6 link-local addresses,fe80::/10[14], [12]. It takes four entries because reverse DNS writes an IPv6 address one hex digit at a time, backwards [15]. A/10fixes the first two digits,fe, and only half of the third, which leaves four possible third digits,8,9,a, andb. Each gets its own entry, written backwards as8.e.fand so on.
A second list underneath, headed “for scoped queries”, repeats the servers once for each network interface, such as en0 for Wi-Fi and another en number for a wired adapter. A VPN or a domain-specific setting adds entries of its own, like the *.corp.example.com example above.
Watching it happen
dig shows a single lookup in detail, including the TTL on each record [16]. On Windows, Resolve-DnsName does the same job [17]:
macOS / Linux
dig www.example.com
dig www.example.com @192.0.2.53 # ask a specific resolver (put its address here)
dig +short www.example.com # just the answer
dig +trace www.example.com # walk root → TLD → authoritative yourself
Windows (PowerShell)
Resolve-DnsName www.example.com
Resolve-DnsName www.example.com -Server 192.0.2.53 # ask a specific resolver (put its address here)
| Option | What it does |
|---|---|
@192.0.2.53 | Sends the question to that server instead of the resolver from your system settings [16]. -Server does the same for Resolve-DnsName [17]. |
+short | Prints a terse answer, usually just the values, without the sections and comments [16]. |
+trace | Skips your recursive resolver and walks the tree itself, starting at the root and following each referral [16]. Resolve-DnsName has no equivalent. |
-x | Reverse lookup, from an address to a name [16]. See reverse lookups. |
Reading dig’s output
Plain dig www.example.com prints something like this. It’s trimmed, the addresses are changed to documentation ranges, and it’s shown as if example.com used the zone in Record types, where www is a CNAME:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2716
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;www.example.com. IN A
;; ANSWER SECTION:
www.example.com. 300 IN CNAME example.com.
example.com. 300 IN A 203.0.113.10
;; Query time: 48 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
status: NOERRORmeans the lookup worked.NXDOMAINmeans the name doesn’t exist at all [7], andSERVFAILmeans the server hit a problem and couldn’t answer [6].flags: rd raare “recursion desired” (dig asked for the whole job) and “recursion available” (the server offers it) [6], the recursive part from earlier.QUESTION SECTIONrepeats what was asked: the name and the record type,Aunless you ask for another.ANSWER SECTIONhas one record per line: the name, the TTL, the class (IN, for internet, on nearly everything), the type, and the value. The first line is the CNAME, and the resolver followed it and includedexample.com’s A record on the second line.SERVERis the resolver that answered, with the port after the#. Here it’s the home router at192.168.1.1. On Linux with systemd-resolved it’s usually127.0.0.53.Query timeis how long the answer took, including any walk the resolver had to do.
Run the same command a minute later, and the same resolver answers from its cache:
;; ANSWER SECTION:
www.example.com. 241 IN CNAME example.com.
example.com. 241 IN A 203.0.113.10
;; Query time: 2 msec
The TTL has counted down by the 59 seconds the record has spent in the cache, and the query time is now just the trip to the resolver and back. When the TTL reaches zero, the resolver drops its copy and the next query goes out again.
Following the referrals with +trace
dig +trace shows the walk from Following one lookup. Trimmed (it also prints DNSSEC records, which +trace turns on [16]) and with addresses changed, it looks like this:
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
;; Received 1097 bytes from 192.168.1.1#53(192.168.1.1) in 13 ms
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
;; Received 1175 bytes from 198.51.100.42#53(l.root-servers.net) in 35 ms
example.com. 172800 IN NS ns1.example.com.
example.com. 172800 IN NS ns2.example.net.
;; Received 510 bytes from 198.51.100.30#53(f.gtld-servers.net) in 46 ms
www.example.com. 300 IN CNAME example.com.
example.com. 300 IN A 203.0.113.10
;; Received 183 bytes from 203.0.113.53#53(ns1.example.com) in 20 ms
Each block ends with a Received ... from line naming the server that sent it:
- First block, from your own resolver: the list of root servers. That’s the only question your resolver gets, and with
@serverit goes to that server instead [16]. - Second block, from a root server: step 3’s first referral, the NS records for
com. - Third block, from a
.comserver: the second referral, the NS records forexample.com. - Last block, from
ns1.example.com: the answer, from the authoritative server.
Watching the packets
You can also watch the raw traffic. DNS normally uses UDP port 53 (falling back to TCP for large answers) [6], [18], so clear the local cache, watch port 53, and make a request:
macOS / Linux
# clear the local cache so the next lookup goes out on the wire
sudo killall -HUP mDNSResponder # macOS
sudo resolvectl flush-caches # Linux with systemd-resolved
# watch DNS traffic
sudo tcpdump -i any udp port 53
# in another terminal
curl -sI https://www.example.com
Windows (PowerShell)
# in a PowerShell window opened as administrator
# clear the local cache so the next lookup goes out on the wire
Clear-DnsClientCache
# watch DNS traffic (Ctrl+C stops it)
pktmon filter add -p 53
pktmon start -c -m real-time
# in another window
curl.exe -sI https://www.example.com
# afterwards, remove the filter
pktmon filter remove
In the tcpdump command, -i any captures on every network interface at once [19], and udp port 53 is a filter that keeps only UDP packets to or from port 53 [20]. On Windows, pktmon filter add -p 53 sets up the same port filter, -c turns on packet capture, and -m real-time prints packets on screen instead of writing a log file [21], [22].
The cache commands come from each system’s own documentation [23], [10], [24]. curl.exe is spelled out because in Windows PowerShell 5.1 plain curl is an alias for a different command [25].
The first request shows the queries going out. Repeat it and there’s little or nothing, because the answer is cached. If you see nothing even the first time, your browser or system may be using DNS over HTTPS, which sends lookups inside ordinary encrypted HTTPS traffic on port 443 [26], so a filter on port 53 never sees them.
Where Route 53 fits
Route 53 is AWS’s DNS service, and it does a few separate jobs that are easy to blur together [27]:
- Domain registration. Registering a domain makes you its owner. The registrar’s main technical job is telling the TLD which name servers are authoritative for your domain, which puts the delegation in place. You can register a domain in one place and host its DNS somewhere else.
- Authoritative DNS, through hosted zones. A hosted zone is the set of records for one zone. When you create a public hosted zone, Route 53 assigns it four name servers and creates the zone’s NS and SOA records. Those four name servers have to be the ones listed at your registrar, or the TLD’s referrals will point somewhere else and your records won’t be used [28].
- Recursive resolution inside your VPCs. Every VPC gets a resolver at its base address plus two, so a VPC using
10.0.0.0/16has its resolver at10.0.0.2[29]. That’s the reserved.2address from AWS VPCs, subnets, and routing. It answers for names inside the VPC and looks everything else up on the internet [30].
Alias records and the zone apex
The name of a zone itself, example.com with nothing in front, is called the zone apex (people also say bare or naked domain) [31]. It’s the top node of that one zone [1] and has nothing to do with the root servers or the root of the tree.
You can put a CNAME on www.example.com, but not on the apex. Two rules collide there. A name that has a CNAME can’t have any other records, because a CNAME means “this name is really that other name” and nothing else [32]. And the apex always has other records: an SOA record and NS records, because those are what make it a zone [1], and usually MX and TXT records too.
It matters as soon as you want example.com itself to point at an Application Load Balancer. An ALB’s IP addresses aren’t fixed, so an A record is a bad fit, and a CNAME to the ALB’s name isn’t allowed. Route 53’s alias records fill that gap: you point the apex at the ALB, and Route 53 looks up its current addresses and answers with those, so to everyone else it looks like an ordinary A record [31]. Other DNS providers offer the same thing under names like ALIAS, ANAME, or CNAME flattening, and the newer HTTPS record type is the standard way to do it for web traffic [33].
Private hosted zones
A private hosted zone holds records that only answer inside the VPCs you associate with it. A query from outside those VPCs doesn’t see the private zone at all and gets looked up on the public internet instead [34]. A private zone for internal.example.com might hold:
| Name | Type | Value |
|---|---|---|
db.internal.example.com | A | 10.0.1.25 |
cache.internal.example.com | A | 10.0.2.40 |
An instance in an associated VPC asks the VPC resolver at 10.0.0.2 for db.internal.example.com and gets 10.0.1.25. A laptop at home asks its usual resolver, which looks on the public internet and finds no such name. So a laptop on a VPN can reach a private address but still fail to resolve its name, unless its DNS queries go to a resolver that can see the private zone.
Route 53 Resolver can bridge that gap in both directions, through endpoints you create in the VPC:
- An inbound endpoint is an address in your VPC that accepts DNS queries from outside it. Resolvers on an office network, reached over a VPN or Direct Connect, send queries for the private names there and get answers from the private zones associated with that VPC [35], [34]. Sending those queries straight to the VPC’s
.2address from outside isn’t supported, and AWS recommends an inbound endpoint instead [36]. - An outbound endpoint goes the other way. With forwarding rules, the VPC resolver sends queries for chosen domains out to resolvers on another network. When rules overlap, the most specific domain wins [36], the same idea as longest prefix match in route tables.
Routing policies
A plain record always returns the same answer. Route 53 can also choose between several answers for the same name [37]:
| Policy | Chooses based on |
|---|---|
| Simple | Nothing. One answer. |
| Weighted | Proportions you set, like 90% to the current version and 10% to a new one |
| Failover | A health check: the primary while it’s healthy, a standby when it isn’t |
| Latency | Whichever AWS Region gives the person asking the lowest latency |
There are a few more that choose by location or by the asker’s address range, all listed in AWS’s guide to routing policies.
A routing policy only decides which address goes in the answer [37]. The client then connects to that address directly, and none of the traffic itself passes through Route 53. Despite the name, routing policies have nothing to do with route tables.
All of these happen at lookup time, so caching still applies. If a failover record has a five-minute TTL, some people keep getting the old answer for up to five minutes after the switch, which is why failover records usually have short TTLs.
Record types
Every record has a name, a TTL, a type, and a value. A small zone for example.com with most of the types you’ll come across, in the format DNS servers use for zone files, looks like this:
example.com. 3600 SOA ns1.example.com. admin.example.com. 2026100601 7200 900 1209600 300
example.com. 3600 NS ns1.example.com.
example.com. 3600 NS ns2.example.net.
example.com. 300 A 203.0.113.10
example.com. 300 AAAA 2001:db8::10
www.example.com. 300 CNAME example.com.
example.com. 3600 MX 10 mail1.example.com.
example.com. 3600 MX 20 mail2.example.com.
example.com. 3600 TXT "v=spf1 include:_spf.mail.example.net -all"
_dmarc.example.com. 3600 TXT "v=DMARC1; p=reject"
example.com. 3600 CAA 0 issue "letsencrypt.org"
_sip._tcp.example.com. 3600 SRV 10 50 5060 sip1.example.com.
Reading the zone file
| Column | Example | Meaning |
|---|---|---|
| Name | www.example.com. | The name the record belongs to |
| TTL | 300 | How many seconds a resolver may cache it |
| Type | CNAME | What kind of record it is |
| Value | example.com. | The data, in a format that depends on the type |
Real zone files and dig output often have one more column between the TTL and the type, the class, which is IN on nearly everything and left out here [6].
Names end in a dot because that dot is the root. A name with the trailing dot is complete. Without it, a zone file treats the name as relative and adds the zone’s own name to the end, so a forgotten dot turns example.com into example.com.example.com. [6].
The SOA line packs the zone’s housekeeping into one record [6]:
| Field | Value | Meaning |
|---|---|---|
| Primary name server | ns1.example.com. | The original source of the zone’s data |
| Admin mailbox | admin.example.com. | admin@example.com, with the first dot standing in for the @ |
| Serial | 2026100601 | A version number that goes up with every change, so secondary name servers can tell their copy is out of date. This one is the date plus a counter [1]. |
| Refresh | 7200 | How often secondary servers check for a new version, in seconds |
| Retry | 900 | How long a secondary waits before trying again after a failed check |
| Expire | 1209600 | How long a secondary keeps answering if it can’t reach the primary (two weeks) |
| Negative TTL | 300 | How long resolvers may cache “this name doesn’t exist” [7] |
The www CNAME turns a lookup for www.example.com into a lookup for example.com, which has the A record. The resolver follows it and returns both [1], which is why dig shows two lines in its answer: the CNAME, then example.com’s A record.
There are over a hundred registered record types [38], but most are obsolete or experimental. These are the ones that matter in practice, grouped by what they’re for.
Addresses and aliases
| Type | Holds | Notes |
|---|---|---|
| A | An IPv4 address [6] | The most common record there is. |
| AAAA | An IPv6 address [15] | The IPv6 counterpart to A. A name can have both. |
| CNAME | Another name: “this name is really that one” [6] | The resolver follows it and looks up the target instead. Not allowed at the zone apex. |
| HTTPS / SVCB | Where and how to connect to a service: alternative names, ports, and supported protocols like HTTP/3 [33] | Newer. Lets a browser learn about HTTP/3 before its first connection. |
| Alias (Route 53) | Another AWS resource, like a load balancer or CloudFront distribution | Not a real DNS type. Route 53 answers with the target’s own A or AAAA records [31]. See alias records. |
Running the zone
| Type | Holds | Notes |
|---|---|---|
| NS | The name servers responsible for a zone [6] | The TLD’s referrals point at these, and they’re what you set at your registrar. |
| SOA | “Start of authority”: housekeeping for the zone [6] | The primary name server, an admin contact, a serial number, timers for secondary servers, and how long to cache “doesn’t exist” answers [7]. Broken down above. |
Reverse lookups
| Type | Holds | Notes |
|---|---|---|
| PTR | A name, for an address [6] | Lives under in-addr.arpa (IPv4) with the address backwards. Set by whoever owns the address block, usually your ISP or cloud provider, not by you. |
To go from an address to a name, use dig -x (plain dig 203.0.113.10 treats the address as a name and won’t find anything). Reverse lookups use PTR records under a special domain, with the address written backwards: 203.0.113.10 is looked up as 10.113.0.203.in-addr.arpa [6], and dig -x builds that name for you [16]. In PowerShell, ask for the PTR record by the backwards name [17]:
macOS / Linux
dig -x 203.0.113.10
Windows (PowerShell)
Resolve-DnsName 10.113.0.203.in-addr.arpa -Type PTR
The PTR record isn’t in the example.com zone from earlier. It lives in a zone under in-addr.arpa run by whoever owns the 203.0.113.0/24 block [6], and there it looks like this:
10.113.0.203.in-addr.arpa. 3600 PTR example.com.
Reverse names use the same tree as forward ones, under their own TLD, arpa. Writing the address backwards is what makes that work: read right to left, the name goes from the biggest block of addresses down to one address, so each level can be delegated to whoever holds that part of the address space [6]. The in-addr.arpa zone itself is served by its own set of name servers [39], and the registries that hand out address blocks delegate reverse DNS for each block to the organization that holds it, which can delegate it on to its own customers [40].
The same shape as the forward tree, read top down: 10.113.0.203.in-addr.arpa. from right to left. The teal lines are delegations. The arpa servers only point the way down, like the com servers do, and the PTR record sits at the bottom with whoever holds the address.
It’s a quick way to see who runs a resolver or server, when the owner has set one up.
Email leans on DNS more than anything else, mostly through TXT records with special formats:
| Type | Holds | Notes |
|---|---|---|
| MX | The mail servers that accept email for the domain, each with a preference number [6] | Lower numbers are tried first, so 10 before 20. |
| TXT: SPF | Which servers are allowed to send email as the domain [41] | Published as a TXT record starting v=spf1. There used to be a dedicated SPF record type, but it’s been removed from the standard [41]. |
| TXT: DKIM | The public key that checks the signature on outgoing email [42] | Lives at <selector>._domainkey.example.com. |
| TXT: DMARC | What receivers should do with email that fails SPF or DKIM, and where to send reports [43] | Lives at _dmarc.example.com. |
Services and security
| Type | Holds | Notes |
|---|---|---|
| TXT (general) | Arbitrary text [6] | Also how outside services check you control a domain, like the _acme-challenge record in Certificates and Trust. |
| SRV | The host and port for a service, with priority and weight [44] | Named _service._protocol.example.com. Used by protocols like SIP and XMPP and some directory services. |
| CAA | Which certificate authorities may issue certificates for the domain [45] | Covered in Certificates and Trust. |
DNSSEC record types
Plain DNS has no way to prove an answer is genuine. DNSSEC adds signatures so a resolver can check that an answer really came from the zone’s owner and wasn’t changed on the way [46]. It adds its own record types [47]:
| Type | Holds |
|---|---|
| DNSKEY | The zone’s public signing keys. |
| RRSIG | A signature over a set of records. |
| DS | A fingerprint of a child zone’s key, published in the parent zone. This is how trust chains down from the root, through the TLD, to your domain. |
| NSEC (and NSEC3) | Signed proof that a name or type doesn’t exist, so “no such name” can’t be forged either. |
Less common record types
| Type | Holds |
|---|---|
| NAPTR | Rewrite rules for turning one kind of identifier into another, mostly used in telephony [48]. |
| SSHFP | The fingerprint of a server’s SSH key, so an SSH client can check it against DNS instead of asking you [49]. |
| TLSA | A pin for a server’s TLS certificate or CA, published in DNS (DANE). Only meaningful with DNSSEC [50]. |
Route 53 supports 17 types: A, AAAA, CAA, CNAME, DS, HTTPS, MX, NAPTR, NS, PTR, SOA, SPF, SRV, SSHFP, SVCB, TLSA, and TXT, plus its own alias records [51].
References
Show all 51 sourcesHide sources
- [1] ↩ a b c d e f g h i j k l m P. Mockapetris, “Domain names - concepts and facilities,” RFC 1034, Internet Engineering Task Force, Nov. 1987. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc1034
- [2] ↩ IANA, “Root Zone Management.” Accessed: Oct. 9, 2026. [Online]. Available: https://www.iana.org/domains/root
- [3] ↩ IANA, “List of top-level domains,” version 2026100900. Accessed: Oct. 9, 2026. [Online]. Available: https://data.iana.org/TLD/tlds-alpha-by-domain.txt
- [4] ↩ IANA, “Root Files.” Accessed: Oct. 9, 2026. [Online]. Available: https://www.iana.org/domains/root/files
- [5] ↩ Root Server Technical Operations Association, “Root Servers.” Accessed: Oct. 5, 2026. [Online]. Available: https://root-servers.org/
- [6] ↩ a b c d e f g h i j k l m n o p q P. Mockapetris, “Domain names - implementation and specification,” RFC 1035, Internet Engineering Task Force, Nov. 1987. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc1035
- [7] ↩ a b c d M. Andrews, “Negative Caching of DNS Queries (DNS NCACHE),” RFC 2308, Internet Engineering Task Force, Mar. 1998. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc2308
- [8] ↩ Microsoft, “Get-DnsClientServerAddress,” Windows PowerShell DnsClient Module Reference. Accessed: Oct. 7, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/dnsclient/get-dnsclientserveraddress
- [9] ↩ systemd project, “systemd-resolved.service,” systemd manual pages. Accessed: Oct. 7, 2026. [Online]. Available: https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html
- [10] ↩ a b The systemd project, “resolvectl(1),” Linux manual pages. Accessed: Oct. 14, 2026. [Online]. Available: https://man7.org/linux/man-pages/man1/resolvectl.1.html
- [11] ↩ Apple, “scutil(8),” macOS manual pages, online copy of the Xcode man pages. Accessed: Oct. 9, 2026. [Online]. Available: https://keith.github.io/xcode-man-pages/scutil.8.html
- [12] ↩ a b c d S. Cheshire and M. Krochmal, “Multicast DNS,” RFC 6762, Internet Engineering Task Force, Feb. 2013. Accessed: Oct. 9, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc6762
- [13] ↩ S. Cheshire, B. Aboba, and E. Guttman, “Dynamic Configuration of IPv4 Link-Local Addresses,” RFC 3927, Internet Engineering Task Force, May 2005. Accessed: Oct. 9, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc3927
- [14] ↩ R. Hinden and S. Deering, “IP Version 6 Addressing Architecture,” RFC 4291, Internet Engineering Task Force, Feb. 2006. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc4291
- [15] ↩ a b S. Thomson, C. Huitema, V. Ksinant, and M. Souissi, “DNS Extensions to Support IP Version 6,” RFC 3596, Internet Engineering Task Force, Oct. 2003. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc3596
- [16] ↩ a b c d e f g h Internet Systems Consortium, “dig: DNS lookup utility,” BIND 9 Administrator Reference Manual: Manual Pages. Accessed: Oct. 7, 2026. [Online]. Available: https://bind9.readthedocs.io/en/stable/manpages.html
- [17] ↩ a b c Microsoft, “Resolve-DnsName,” Windows PowerShell DnsClient Module Reference. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/dnsclient/resolve-dnsname
- [18] ↩ J. Dickinson, S. Dickinson, R. Bellis, A. Mankin, and D. Wessels, “DNS Transport over TCP - Implementation Requirements,” RFC 7766, Internet Engineering Task Force, Mar. 2016. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc7766
- [19] ↩ The Tcpdump Group, “tcpdump(1): dump traffic on a network,” tcpdump man pages. Accessed: Oct. 7, 2026. [Online]. Available: https://www.tcpdump.org/manpages/tcpdump.1.html
- [20] ↩ The Tcpdump Group, “pcap-filter(7): packet filter syntax,” tcpdump man pages. Accessed: Oct. 7, 2026. [Online]. Available: https://www.tcpdump.org/manpages/pcap-filter.7.html
- [21] ↩ Microsoft, “Pktmon command formatting,” Microsoft Learn: Windows Server. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/windows-server/networking/technologies/pktmon/pktmon-syntax
- [22] ↩ Microsoft, “pktmon start,” Microsoft Learn: Windows Commands. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/pktmon-start
- [23] ↩ Apple, “Reset the DNS cache in OS X,” Apple Support. Accessed: Oct. 6, 2026. [Online]. Available: https://support.apple.com/en-us/101481
- [24] ↩ Microsoft, “Clear-DnsClientCache,” Windows PowerShell DnsClient Module Reference. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/powershell/module/dnsclient/clear-dnsclientcache
- [25] ↩ Microsoft, “curl on Windows,” Microsoft Learn, May 19, 2026. Accessed: Oct. 6, 2026. [Online]. Available: https://learn.microsoft.com/en-us/windows/curl/
- [26] ↩ P. Hoffman and P. McManus, “DNS Queries over HTTPS (DoH),” RFC 8484, Internet Engineering Task Force, Oct. 2018. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc8484
- [27] ↩ Amazon Web Services, “Amazon Route 53 concepts,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html
- [28] ↩ Amazon Web Services, “Considerations when working with public hosted zones,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-public-considerations.html
- [29] ↩ Amazon Web Services, “Understanding Amazon DNS,” Amazon VPC User Guide. Accessed: Oct. 7, 2026. [Online]. Available: https://docs.aws.amazon.com/vpc/latest/userguide/AmazonDNS-concepts.html
- [30] ↩ Amazon Web Services, “What is Route 53 VPC Resolver?” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver.html
- [31] ↩ a b c Amazon Web Services, “Choosing between alias and non-alias records,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html
- [32] ↩ R. Elz and R. Bush, “Clarifications to the DNS Specification,” RFC 2181, Internet Engineering Task Force, Jul. 1997. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc2181
- [33] ↩ a b B. Schwartz, M. Bishop, and E. Nygren, “Service Binding and Parameter Specification via the DNS (SVCB and HTTPS Resource Records),” RFC 9460, Internet Engineering Task Force, Nov. 2023. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc9460
- [34] ↩ a b Amazon Web Services, “Working with private hosted zones,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html
- [35] ↩ Amazon Web Services, “Forwarding inbound DNS queries to your VPCs,” Amazon Route 53 Developer Guide. Accessed: Oct. 8, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-forwarding-inbound-queries.html
- [36] ↩ a b Amazon Web Services, “Resolving DNS queries between VPCs and your network,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resolver-overview-DSN-queries-to-vpc.html
- [37] ↩ a b Amazon Web Services, “Choosing a routing policy,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html
- [38] ↩ Internet Assigned Numbers Authority, “Domain Name System (DNS) Parameters: Resource Record (RR) TYPEs.” Accessed: Oct. 6, 2026. [Online]. Available: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
- [39] ↩ J. Abley and T. Manderson, “Nameservers for IPv4 and IPv6 Reverse Zones,” RFC 5855, Internet Engineering Task Force, May 2010. Accessed: Oct. 9, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc5855
- [40] ↩ ARIN, “Reverse DNS,” American Registry for Internet Numbers. Accessed: Oct. 9, 2026. [Online]. Available: https://www.arin.net/resources/manage/reverse/
- [41] ↩ a b S. Kitterman, “Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1,” RFC 7208, Internet Engineering Task Force, Apr. 2014. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc7208
- [42] ↩ D. Crocker, Ed., T. Hansen, Ed., and M. Kucherawy, Ed., “DomainKeys Identified Mail (DKIM) Signatures,” RFC 6376, Internet Engineering Task Force, Sep. 2011. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc6376
- [43] ↩ T. Herr, Ed. and J. Levine, Ed., “Domain-Based Message Authentication, Reporting, and Conformance (DMARC),” RFC 9989, Internet Engineering Task Force, May 2026. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc9989
- [44] ↩ A. Gulbrandsen, P. Vixie, and L. Esibov, “A DNS RR for specifying the location of services (DNS SRV),” RFC 2782, Internet Engineering Task Force, Feb. 2000. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc2782
- [45] ↩ P. Hallam-Baker, R. Stradling, and J. Hoffman-Andrews, “DNS Certification Authority Authorization (CAA) Resource Record,” RFC 8659, Internet Engineering Task Force, Nov. 2019. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc8659
- [46] ↩ R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose, “DNS Security Introduction and Requirements,” RFC 4033, Internet Engineering Task Force, Mar. 2005. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc4033
- [47] ↩ R. Arends, R. Austein, M. Larson, D. Massey, and S. Rose, “Resource Records for the DNS Security Extensions,” RFC 4034, Internet Engineering Task Force, Mar. 2005. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc4034
- [48] ↩ M. Mealling, “Dynamic Delegation Discovery System (DDDS) Part Three: The Domain Name System (DNS) Database,” RFC 3403, Internet Engineering Task Force, Oct. 2002. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc3403
- [49] ↩ J. Schlyter and W. Griffin, “Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints,” RFC 4255, Internet Engineering Task Force, Jan. 2006. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc4255
- [50] ↩ P. Hoffman and J. Schlyter, “The DNS-Based Authentication of Named Entities (DANE) Transport Layer Security (TLS) Protocol: TLSA,” RFC 6698, Internet Engineering Task Force, Aug. 2012. Accessed: Oct. 5, 2026. [Online]. Available: https://www.rfc-editor.org/rfc/rfc6698
- [51] ↩ Amazon Web Services, “Supported DNS record types,” Amazon Route 53 Developer Guide. Accessed: Oct. 5, 2026. [Online]. Available: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html
Every source cited across the primers is collected on one page.