Skip to content
RU
← All articles

Ghost Domain: Why a Removed Delegation Still Resolves

In short. A resolver learns your nameservers twice — once from the parent zone that delegates to you, and again from your own zone, which answers authoritatively about itself. When it prefers the second and refreshes it on every query, a delegation can keep resolving long after the parent stopped publishing it. That is the ghost domain problem, and its ordinary form is a nameserver migration that will not finish.

Two sources for the same fact

Delegation is a handoff. The parent zone publishes NS records saying "ask these servers about this name", and the zone those servers hold publishes its own NS records saying the same thing. In a healthy setup the two agree and nobody notices there are two.

They are not equally authoritative in the way most people assume. The parent's records are a referral — they point onward. The child's records come from the zone itself and arrive in an authoritative answer. Resolvers have to decide which to cache and which to trust when they disagree, and the details of that decision are where this problem lives.

The important asymmetry: the parent's copy expires on the parent's TTL, which you do not control once you have left. The child's copy expires on a TTL the child chooses — and the child can keep resending it.

A delegation shown twice: once as a referral pointing downward from a parent zone and once as a self-declaration inside the child zone
The same delegation exists in two places. One of them is written by whoever holds the zone, and they can keep rewriting it.

How a name outlives its delegation

The sequence is short and it is the whole problem:

  1. A resolver queries the name and follows the parent's referral to the authoritative servers.
  2. Those servers answer, and the answer includes their own NS records with whatever TTL they choose.
  3. The resolver caches those NS records.
  4. The delegation is removed at the parent — the name should stop resolving.
  5. The resolver, still holding the child's NS records, queries those servers directly rather than starting from the parent again.
  6. The servers answer and refresh their own NS records once more.

Steps five and six are a loop. As long as any resolver keeps asking, the answer keeps arriving and the cache entry keeps renewing. The removal at the parent never gets consulted, because nothing in that loop goes back to the parent.

Where the name comes from

The behaviour was documented in security research as an abuse technique: a domain used for something malicious is suspended by the registry, and it keeps resolving anyway because its own nameservers refresh the delegation faster than any cache expires. The takedown succeeds on paper and fails in practice, sometimes for a long time.

Resolver implementations were hardened afterwards — most now treat records from the parent as more credible for delegation purposes, re-check the parent when a cache entry is refreshed, or cap how long a child can extend its own delegation. The behaviour is much rarer than it was, and "much rarer" is not "gone": resolvers differ, and the internet runs a wide spread of versions.

The version you are far more likely to meet

Nothing about the mechanism requires an attacker. The same loop runs during an ordinary nameserver migration, and it produces a symptom that looks like nonsense:

You moved DNS providers, the registrar shows the new nameservers, the parent has published them — and some resolvers keep asking the old provider.

The old provider is still answering, because you have not deleted the zone there yet, and every answer it gives refreshes its own NS records in whichever caches still hold them. Meanwhile the change looks complete from every angle you can see: the registrar is correct, dig +trace from a cold cache is correct, and most of the world is fine.

# What the parent says — the referral, from a TLD server
dig +norecurse NS example.com @$(dig +short NS com. | head -1)

# What the zone says about itself — the child copy
dig +short NS example.com @ns1.new-provider.example

# What a given resolver currently believes, without making it re-ask
dig +norecurse NS example.com @1.1.1.1

Three different answers are possible and each means something distinct. Parent and child agreeing with a resolver that does not is a cache waiting to expire. Parent and child disagreeing is a migration that is not finished, and it is the case where this can persist.

A cached delegation being refreshed in a loop by the servers it points to, while the parent's updated record is never consulted
The loop never returns to the parent. Whoever keeps answering keeps renewing the record that points at them.

What to do during a nameserver migration

The mitigation is boring and it works: make both copies agree before you change the parent, and keep them agreeing until every cache has turned over.

  1. Create the zone at the new provider first, with records identical to the old one.
  2. Publish the new NS records inside the old zone too. This is the step most migrations skip. It makes the child's self-declaration point at the new servers, so a refreshed cache entry now refreshes the correct delegation.
  3. Then change the delegation at the registrar, so the parent agrees as well.
  4. Leave the old zone serving, unchanged and correct, for well past the old NS TTL. Deleting it early converts a slow migration into an outage for anyone still pointed there.
  5. Verify all three views — parent, child, and several public resolvers — before removing anything.

Step two is the one that turns this from a wait into a controlled change. If the old nameservers are still answering and still naming themselves, the refresh loop keeps them alive; if they are answering and naming the new servers, the same loop carries the migration forward instead of holding it back.

The NS TTL you set is not the one that matters

As with every DNS change, the lifetime that governs a migration was published before it — but delegation has a second complication. The NS TTL in your zone and the NS TTL at the parent are separate values, set by different parties, and a resolver may be holding either.

CopyWho sets the TTLWhen it matters
Parent NS (referral)The registry or registrarResolvers starting from a cold cache
Child NS (in your zone)YouResolvers that already hold your delegation
SOA minimumYouNegative answers, if the name stops existing

Lower the child NS TTL well ahead of a planned migration, the same way you would lower an A record TTL. It is the copy you control, and it is the one that decides how quickly resolvers already talking to you will accept a change. The general rule is covered in the TTL guide, and the reason lowering it afterwards achieves nothing is the same in both cases.

A three-view check you can run before and after

The state of a delegation is not one value, so a single lookup cannot describe it. Read all three views in one pass and compare:

#!/bin/sh
# Parent, child and a public resolver — the three copies that can disagree
D=example.com
TLD=$(echo "$D" | awk -F. '{print $NF}')

echo "parent (referral):"
dig +norecurse +short NS "$D" @"$(dig +short NS "$TLD". | head -1)" | sort | sed 's/^/  /'

echo "child (the zone about itself):"
dig +short NS "$D" | sort | sed 's/^/  /'

echo "public resolvers, cached:"
for r in 1.1.1.1 8.8.8.8 9.9.9.9; do
  printf '  %-9s ' "$r"
  dig +norecurse +short NS "$D" @"$r" | sort | tr '
' ' '
  echo
done

Three identical sets means the delegation is settled. Parent and child agreeing while a resolver lags is an expiry you can wait out. Parent and child disagreeing is the state to act on, and the direction of the disagreement tells you which half of the migration is unfinished.

If you are the one trying to remove a name

Registry suspension, a takedown request or an abuse report all act at the parent. If the name's own servers keep answering, expect resolution to continue for some resolvers, and expect the duration to be unpredictable because it depends on implementations you do not operate.

What actually ends it is the authoritative servers ceasing to answer — either because they are withdrawn, or because the operator stops serving the zone. That is a different conversation with a different party, and knowing which lever does what saves the argument about why the removal "did not work".

Two levers, one acting on the parent delegation and one on the answering servers, with only the second stopping the responses
Removing the delegation and stopping the answers are separate actions. Only the second one ends the loop.

How to check your own domain

Compare the two copies directly. The DNS lookup reads NS records from outside your network, and the WHOIS lookup shows the nameservers registered at the registrar — which is the parent's view. When those two disagree, you have a delegation that is only half changed, and that is the state this problem lives in.

The propagation check queries resolvers in several regions, which is how you find out whether the disagreement is theoretical or whether real resolvers are still being sent to the old servers.

Because a half-finished delegation looks healthy from most angles, it is worth watching rather than checking once. Scheduled DNS monitoring records the NS set over time and alerts on change, which catches both an unfinished migration and an unauthorised one — the latter being the case where somebody else has changed where your domain points.

A registrar view and a zone view of the same delegation shown side by side, disagreeing
Registrar and zone are two views of one delegation. Comparing them is the check that finds a migration stuck halfway.

Frequently asked questions

Is this still exploitable?

Far less than when it was first documented. Major resolvers were hardened to prefer the parent's delegation and to limit how long a child can extend its own. Variants have resurfaced over time, and the internet runs many resolver versions, so "hardened" describes the common case rather than all of them.

Why does my nameserver change seem stuck?

Most often because the old zone is still being served and still names the old servers. Every answer it gives refreshes that delegation in resolvers already holding it. Publish the new NS records inside the old zone as well, and the same refresh carries the change forward.

Should I delete the old zone right after switching?

No. Any resolver still pointed there stops getting answers, which turns a gradual migration into an outage for those users. Leave it serving correct data well past the old NS TTL, then remove it.

Which NS TTL should I lower before migrating?

The one in your own zone — that is the copy you control and the one resolvers already holding your delegation will use. The parent's TTL is set by the registry and is not yours to change.

How do I see what a resolver currently believes?

Query it with +norecurse. That returns its cached answer without making it fetch a fresh one, which is the only way to observe the cache rather than replace it.

Does DNSSEC prevent this?

It authenticates answers rather than governing which copy of a delegation a resolver prefers or how long it keeps it. It raises the cost of forging records; it is not a mechanism for expiring a delegation faster.

Checklist

  • Remember there are two copies of your delegation, and you only control one.
  • Lower the NS TTL in your own zone ahead of a migration, never during.
  • Create the new zone before touching the registrar.
  • Publish the new NS records inside the old zone as well — this is the step that gets skipped.
  • Change the delegation at the registrar only after both zones agree.
  • Keep the old zone serving correct data well past the old NS TTL.
  • Compare registrar view against zone view before declaring a migration done.
  • Use +norecurse to read a resolver's cache without refreshing it.
  • Expect a takedown at the parent not to stop answers from servers still serving.
  • Monitor the NS set — an unfinished migration and an unauthorised change look alike.

Check your website right now

Check your site's DNS →
More articles: DNS
DNS
Best Public DNS Servers 2026: Fastest, Safest, IPv4 & IPv6
21.07.2026 · 1 702 views
DNS
How to Flush DNS Cache: Windows, Mac, Linux, Browsers
15.04.2026 · 1 133 views
DNS
MX Records for Email: Step-by-Step Setup Guide
15.04.2026 · 1 064 views
DNS
DNS Not Resolving: 8 Causes and How to Fix
15.04.2026 · 948 views