The Domain Resolved Everywhere Except Where I Was Sitting

A CNAME that dig confirmed, a browser that refused, and a certificate stuck on pending. Three separate caches pretending to be one problem.

Share
The Domain Resolved Everywhere Except Where I Was Sitting. Abstract error autopsy illustration in orange and dark grey on debugly.dev

I pointed a custom domain at a machine, waited the customary few minutes, and got ERR_NAME_NOT_RESOLVED in the browser while dig told me the record was live. Then the record started resolving and I got a certificate error instead. Then the certificate arrived and one colleague still could not load the site.

Three symptoms, one after the other, and each one felt like the previous fix had failed. They were unrelated.

The short answer

You are looking at three independent caches: your stub resolver, your recursive resolver, and the certificate issuance step that cannot begin until the record is globally visible. A CNAME that dig resolves from one machine says nothing about what your laptop's resolver has cached, and nothing at all about whether the issuing authority can see it yet.

Query the authoritative nameserver directly, not your local resolver, and treat certificate issuance as a step that starts only after DNS is genuinely propagated.

Tested against Ubuntu 24.04, systemd-resolved 255, dig 9.20.

Cause one: your stub resolver is answering from memory

On a modern Linux desktop, dig example.com does not necessarily leave your machine. systemd-resolved sits in front of everything with its own cache, and on macOS mDNSResponder does the same. If you queried the name before you created the record, the negative response was cached, and negative caching is why "I set it up and it stopped working after I checked too early" is a real phenomenon.

# what your machine currently believes
resolvectl query app.example.com
resolvectl statistics          # look at the cache hit count

# clear it
sudo resolvectl flush-caches

# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

The fix is to stop asking your own machine. Ask the authority.

# find who is authoritative for the zone
dig +short NS example.com

# ask that server directly, bypassing every cache in between
dig @ns1.registrar-servers.com app.example.com CNAME +norecurse

If the authoritative server returns your CNAME and your laptop does not, the record is correct and you are looking at a cache. That distinction takes ten seconds to establish and saves you from editing a DNS record that was already right.

Cause two: the recursive resolver is holding the old TTL

Above your stub sits whatever resolver your network uses, and it honours the TTL that was in effect when it cached the previous answer. If the record previously had a 24 hour TTL, that is how long some resolvers will keep serving the old value, regardless of what you have changed it to now.

This is the one people get angry about, and it is working as designed. The lesson is operational rather than technical: lower the TTL to 300 seconds a day before you plan to change a record. Nobody does this the first time. Everybody does it the second time.

You can confirm what is cached and how long it has left:

# the TTL counts down on repeated queries against a caching resolver
dig @1.1.1.1 app.example.com +noall +answer
dig @8.8.8.8 app.example.com +noall +answer

Different public resolvers will show different remaining TTLs, which is itself useful. If 1.1.1.1 has the new record and 8.8.8.8 does not, nothing is broken, you are simply mid propagation.

Cause three: the certificate cannot be issued until DNS is public

This is the failure that looks like a platform bug and is not.

Automatic HTTPS works by proving control of the domain, and the proof requires the issuing authority to resolve your name to the right place from its vantage point. Your laptop resolving it is irrelevant. Until the record is visible to the outside world, issuance sits in pending and the browser correctly refuses the connection, because there is no certificate yet.

The sequence on a platform with automatic certificates, using Krova Cloud as the example since that is what I run:

  1. You add a CNAME from app.example.com to dns.krova.cloud.
  2. The platform detects the record and requests a certificate.
  3. Validation succeeds only if the authority resolves your name correctly.
  4. HTTPS starts working, typically within a minute of step 3.

Steps 2 to 4 are fast. Step 1 to step 2 is entirely at the mercy of your registrar and your TTLs, and that is where all the waiting actually happens. Blaming the certificate for DNS latency is the single most common misdiagnosis here.

The reason a CNAME is used rather than an A record is that no public IPv4 is assigned to the machine at all. Traffic arrives at the edge, is matched by hostname, and is forwarded inward. That is also why the machine itself needs no open inbound port for this to work, which surprises people the first time. I wrote about the inbound default deny model separately.

Cause four: an apex domain that cannot hold a CNAME

If you are trying to point example.com rather than app.example.com, the RFCs do not permit a CNAME at the zone apex, because the apex must also hold SOA and NS records and a CNAME cannot coexist with other records at the same name.

Your options are the ones every provider offers under a different brand name:

Approach Registrar name Notes
CNAME flattening ALIAS, ANAME, CNAME flattening Resolver side synthesis of an A record. Cleanest option.
Redirect the apex URL redirect record example.com sends a 301 to www.example.com. Perfectly acceptable.
Static A record A Only if the target address is genuinely stable.

Cloudflare, Route 53 and DNSimple all support flattening. Several budget registrars do not, and that is worth checking before you buy the domain rather than after.

A diagnosis order that works

# 1. is the record correct at the source
dig @$(dig +short NS example.com | head -1) app.example.com CNAME +norecurse

# 2. is it visible to the wider internet
dig @1.1.1.1 app.example.com +short
dig @8.8.8.8 app.example.com +short

# 3. is my own machine lying to me
resolvectl query app.example.com

# 4. does the certificate exist yet
echo | openssl s_client -connect app.example.com:443 -servername app.example.com 2>/dev/null \
  | openssl x509 -noout -subject -dates

Work down that list and the ambiguity disappears. If step 1 fails, fix the record. If step 1 passes and step 2 fails, wait, because propagation is not something you can accelerate. If step 2 passes and step 3 fails, flush your cache. If steps 1 to 3 pass and step 4 fails, then and only then is it worth looking at the platform.

Prevention

Lower the TTL to 300 before any planned change, at least 24 hours ahead. This is the single highest value habit in this entire post.

Never diagnose DNS with your own resolver. Use @ and query the authority. Your laptop is the least reliable witness available.

Expect certificate issuance to begin after propagation, not alongside it. The pending state is usually accurate and usually about DNS.

Check apex support before you buy the domain. A registrar without flattening will force a www redirect you did not plan for.

Give it fifteen minutes before changing anything. Most of the incidents I have watched people create in this area came from editing a correct record while it was still propagating, which resets the clock and adds a second wrong answer to the caches.