How to Fix DNS Propagation That Never Seems to Finish
What people call DNS propagation is almost never propagation. Nothing is being pushed anywhere. Your new record exists the moment you save it on the authoritative nameserver, and the delay you are watching is caching: resolvers and client machines holding on to the old answer until its TTL expires. Once you accept that, the fix becomes a matter of finding out who is still holding the stale answer and why.
Why DNS Propagation Is Really a Cache Expiry Problem
DNS is a pull system. A recursive resolver, the one your laptop or your ISP hands queries to, walks the delegation chain from the root, to the top level domain, to your authoritative nameservers, and asks for the record. It then stores the answer for the number of seconds in the record's TTL field and serves that cached copy to everyone behind it until the timer runs out.
That chain of caches is the whole story. There is your operating system resolver cache, your router, your ISP's recursive resolvers, and any public resolver your users happen to be pointed at. Each one holds its own copy with its own countdown. Changing the record at the source does not reach into any of those caches. It only changes what the next uncached query will return. So the practical ceiling on how long a change takes to be visible is the TTL that was on the record before you changed it, not the TTL you set afterwards. If the old record had a long TTL, resolvers that fetched it just before your edit will keep serving it for that full duration.
This is why the standard advice is to lower the TTL well before a planned migration. If you drop the TTL to something short and then wait at least one old TTL period, the caches drain naturally, and the cutover becomes nearly instant. Lowering the TTL at the same moment as the change does nothing for anyone who already cached the old value.
Checking What a Resolver Actually Returns
Stop testing with your browser. The browser has its own cache, the operating system has another, and your local resolver has a third. Query the authoritative servers directly and query public resolvers explicitly, and compare.
$ dig +short example.com A
203.0.113.10
$ dig @ns1.example.net example.com A +noall +answer
example.com. 300 IN A 203.0.113.10
The second form asks a specific nameserver, bypassing your local resolver entirely. If the authoritative answer is correct there, the change is live at the source and everything else is caching. Note the TTL in the answer section: that is the value the resolver will now hold for the record, counted down from the moment it was fetched.
To see the TTL counting down, which tells you the answer is coming from a cache rather than fresh from the authoritative server, query the same resolver twice with a gap between them.
$ dig @1.1.1.1 example.com A +noall +answer
example.com. 287 IN A 203.0.113.10
$ sleep 10
$ dig @1.1.1.1 example.com A +noall +answer
example.com. 277 IN A 203.0.113.10
A TTL that decreases between queries means you are reading from cache. A TTL that resets to the full configured value each time means you are hitting the authoritative server. That distinction alone resolves most confusion about whether a change has gone live.
For the full delegation path, including which nameservers are actually being consulted, use trace mode.
$ dig +trace example.com A
This walks the chain step by step and shows you exactly where the answer is coming from. If the trace ends at nameservers you no longer recognise, your registrar delegation is still pointing somewhere else, and no amount of waiting will fix a record that is being served by the wrong authority.
Negative Caching and the SOA Minimum
Positive answers are not the only thing that gets cached. Negative answers are cached too, and this trips people up constantly. When a resolver asks for a name that does not exist, the authoritative server replies with an SOA record in the authority section, and the resolver caches that non existence for the lesser of the SOA minimum field and the SOA record's own TTL.
$ dig example.com SOA +noall +answer
example.com. 3600 IN SOA ns1.example.net. hostmaster.example.com. (
2024010101 7200 3600 1209600 300 )
In that SOA line the final number, the minimum, governs how long a negative answer sticks around. If you created a subdomain that previously did not exist, some resolvers may have cached its absence, and they will keep reporting it as missing until that timer expires. This is the classic "I added the record an hour ago and it still does not resolve" complaint, and it has nothing to do with the record you just added.
Check the SOA before a big change. If the minimum is large and you are about to create names that never existed, expect a wait on the negative caches you cannot reach.
What You Can and Cannot Control
You control the records, the TTLs, and the delegation at your registrar. You do not control the resolvers in between, and you cannot flush them. There is no command that clears a public recursive resolver's cache on demand, and no support ticket that will do it for you. Anyone who tells you otherwise is describing a service that does not exist at the protocol level.
What you can do is verify. Query the authoritative servers to confirm the record is correct at the source. Query several public resolvers by IP to see how far the new value has spread. Watch the TTL countdown to confirm you are reading cache rather than a fresh answer. Check the delegation with a trace. Check the SOA minimum if the problem involves a name that did not previously exist. And remember that a client's own operating system cache sits in front of everything, so a machine that resolved the old value minutes ago may keep serving it even after the resolver has moved on. Flushing the local cache is the one thing you can force.
On Linux systems running a local caching resolver, restarting that service clears it. On Windows, ipconfig /flushdns does the same job. On macOS, the command has changed between releases, so check the current form for your version rather than trusting a snippet from memory. These commands only affect the machine you run them on. They do nothing for anyone else.
What to Do Next
If you are mid migration and watching a change crawl across the internet, stop refreshing the browser and start querying authoritative servers directly. Confirm the record is right at the source, note the TTL, and then be patient for exactly that long. If you are planning a change, lower the TTL first and wait out the old value before you touch anything else. And if a name that never existed before is the one misbehaving, look at the SOA minimum rather than the record you just created, because the wait you are experiencing was decided long before you made the edit.
