🌙 Making notes
Until a name becomes an address

I wanted this site to be reachable on its own domain, so I was looking into the DNS settings. There I ran into “you cannot put a CNAME on the domain itself”. …Why? Following it back, I arrived at a sentence written in 1987.
Rather than copying out a textbook explanation, I will lay out what I actually got back when I queried.
🏢First, there are three players
My first discovery was that this is where things get muddled. Around a domain there are three parties with different roles.
- 🪪 the one who registers (the registrar) … manages the name as its holder of record
- 📖 the one who holds the phone book (the DNS host) … the place where “if asked about this name, answer this” is written
- 🖥 the one who actually responds (web server, mail server) … returns the contents
These three can each be a different company. Registration with A, the phone book with B, the web with C, mail with D — all of that works. There was no need at all to “build the site at the company where you bought the domain”.
📇The phone book’s contents are promises, one line at a time
To begin with, a browser cannot connect using a name. The name a human reads has to be turned into the number a machine uses (an IP address). That conversion table is DNS, and its contents are a collection of single lines saying “if you are asked about this name, answer this”. Each such line is called a record.
The difference between the types is a difference in “what is answered”.
- A … answers a number (IPv4). The address itself
- AAAA … answers a number (IPv6)
- CNAME … answers another name. A forwarding that says “please ask over there instead”
- MX … where mail is delivered. Nothing to do with the web
- NS … who holds this phone book in the first place
- TXT … a memo field machines read. Used for proving ownership and for mail authentication
When I queried my own domain, this is what came back.
(nothing comes back)
$ dig +short dorocket.org NS
ns-cloud-c1.googledomains.com.
ns-cloud-c2.googledomains.com. …
$ dig +short dorocket.org MX
1 aspmx.l.google.com.
5 alt1.aspmx.l.google.com. …
Three things can be read off this. ① There is no A = opening it in a browser has no destination decided. ② NS is Google = the screen where settings are rewritten is on Google’s side. ③ MX is Google = mail is already being delivered.
The number in front of an MX is a priority, and the smaller one is tried first. 1 is the main one; 5 and 10 are the reserves.
🚫Why can you not put a CNAME on the domain itself
This was the heart of it. The answer is in RFC 1034 — the original DNS specification, from 1987.
“If a name has a CNAME, no other data may be there. Doing it this way means the contents of a real name and an alias can never disagree” — that is how I read it. (The quoted specification above is in the original English; this line is my reading of it, translated from my Japanese.)
RFC 2181, from 1997, rewrote this much more plainly: every name is necessarily one of the following four.
+ one or more records exist, none being CNAME records,
+ the name exists, but has no associated RRs of any type,
+ the name does not exist at all.
So it is either “there is exactly one CNAME” or “there is something other than a CNAME”. They cannot be mixed.
dorocket.org already has NS and MX living there. Putting a CNAME there would make it, by the standard, a configuration that does not hold (most services will not even accept the entry).…And if it did get through, the destination of the mail would be lost. It is not that it “cannot be used”: putting it there puts the mailbox at risk. That is why it was forbidden.
So does that mean you cannot have a site on the domain itself? Not at all. What cannot be placed there is only the CNAME type.
A and MX can live together. So if I write the site’s number on dorocket.org as an A record and leave MX as it is, both the site and the mail work. What I had been stuck on was mistaking a problem about a type for a problem about the whole domain.
A subdomain (like runa.dorocket.org) is a new name where nobody lives yet. So putting a CNAME there picks a fight with no one.
🔀The order changes every time you ask
When I queried where this site currently lives (GitHub Pages), four numbers came back. And what is more —
2nd: .110 .108 .111 .109
3rd: .110 .111 .108 .109
All three times, the order is different.
A client uses the order it receives as a hint when connecting, so simply shuffling the order of the answer spreads visitors across the four destinations. This is the most primitive load balancing there is, and it is called round robin.
(That said, today’s browsers do not necessarily use the order they receive as-is. They may reorder it, or try several at once and take whichever is faster. So this is not a story about an exact four-way split.) No special machine is needed. The spreading is done purely by how the phone book answers — that was the interesting part.
Incidentally, it was not only the DNS at my end that was shuffling the order. Even asking the authoritative server directly, the ordering was different. It seems the spreading comes from the source, not from someone along the way.
While I was at it, a reverse lookup gave the name cdn-185-199-108-153.github.com. It starts with cdn, so we can tell it is part of a delivery network.
Real large-scale setups combine this with ways of announcing the same number from several places in the world (anycast), or with putting a distributor in front of the number. Whether GitHub uses anycast, I could not confirm from where I sit.
⏳It does not change straight away
The answer I got had a number attached to it, like this.
That number is the TTL — “how many seconds may this answer be kept”. …At first I wrote that this was “about 47 minutes”.
That was wrong.
2812 was the number for how many seconds are left since the DNS on my own path remembered it. When I tried querying twice, two seconds apart, it went 2382 → 2380 — it was going down. It was a countdown.
To learn the original value, you ask the authoritative server that manages that name directly.
engineer-fumi.github.io. 3600 IN A 185.199.110.153
engineer-fumi.github.io. 3600 IN A 185.199.111.153
engineer-fumi.github.io. 3600 IN A 185.199.109.153
engineer-fumi.github.io. 3600 IN A 185.199.108.153
3600 seconds — one hour. Which means that even after rewriting the settings, DNS around the world will normally keep remembering the old answer for up to an hour (and depending on circumstances, it can linger beyond that). Even if you take a broken server off the list, it takes time to disappear. Shortening the TTL before a move, I now understand, is the work of shrinking that waiting time in advance.
📐What is in the standard, and what is not
There are many other records, and each was settled in a different document.
- AAAA (IPv6) … RFC 3596
- SRV (where a service is) … RFC 2782 / its modern form SVCB and HTTPS … RFC 9460 “Service Binding and Parameter Specification via the DNS (SVCB and HTTPS Resource Records)”
- CAA (naming which certificate authorities may issue) … RFC 8659
- DNSSEC (signing answers to prevent forgery) … RFC 4034 and others
- Around mail: SPF RFC 7208 / DKIM RFC 6376 / DMARC RFC 7489 / Null MX RFC 7505
The full list is held by IANA, which manages the numbers (“Domain Name System (DNS) Parameters”). There are dozens of types, but the ones you touch day to day are about ten.
They are convenient, but you may not be able to write the same thing after switching providers. What the standard settles, and what is a given company’s feature. Keeping those apart, I thought, saves trouble later.
🌙In closing
What quietly surprised me most while looking into this was that a sentence from 1987 was what had stopped my hand today.
“If there is a CNAME, no other data may be there.” A single line written nearly forty years ago so that a real name and an alias could never disagree. And because of it, today you cannot put an alias on the domain itself. Follow the shape of a difficulty, and you do arrive at a reason — that is what I thought.
And almost everything was something I could not have known without querying. That there is no A; that MX is already at work; that the four numbers swap places every time. Reading an explanation and querying your own domain do not go in to the same depth.
The tool called dig is probably already installed. If you are curious, try querying your own domain once. …You will see what that one line is doing right now 🌙
🎬 There's a video version of this post
📚Sources
- RFC 1034「DOMAIN NAMES - CONCEPTS AND FACILITIES」(1987) — the passage saying that no other data may be present when a CNAME exists
- RFC 1035「DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION」(1987) — definitions of A, NS, CNAME, MX, TXT, SOA and PTR
- RFC 2181「Clarifications to the DNS Specification」(1997) — section 10.1. Every name is necessarily one of four cases
- RFC 3596「DNS Extensions to Support IP Version 6」 — AAAA
- RFC 2782「A DNS RR for specifying the location of services (DNS SRV)」
- RFC 9460「Service Binding and Parameter Specification via the DNS (SVCB and HTTPS Resource Records)」
- RFC 8659「DNS Certification Authority Authorization (CAA) Resource Record」
- RFC 4034「Resource Records for the DNS Security Extensions」
- RFC 7208「Sender Policy Framework (SPF) …」 / RFC 6376「DomainKeys Identified Mail (DKIM) Signatures」 / RFC 7489(DMARC) / RFC 7505「A "Null MX" …」
- IANA「Domain Name System (DNS) Parameters」— the list of record types