OLD ZONE → 404NEW ZONE → SITE

The deploy moved the files. The delegation still picks who answers.

Illustrative failure path. Trace the delegation before changing any records.

Deployed, Not Live: How a Site Can Reach Its Old Host

Moving site files does not by itself update DNS. When active records or cached answers still point to an old host, visitors may reach it after a migration.

Published:
Reading time:
10 minutes

A deploy pipeline reported success. The build artifacts were correct. The new hosting platform had the site ready.

My domain still returned a 404 from the hosting platform I had stopped deploying to months earlier.

The site had moved. DNS and routing were among the things I needed to investigate.

Each system reported accurately about the part it owned. The deploy pipeline knew the files were there. It did not know whether visitors would ever reach them.

This kind of failure is not specific to one stack or one vendor. To see how it can happen, start with what occurs between typing a domain name and loading a page.

What DNS Does


DNS stands for Domain Name System. It lets software look up information about a domain name. For a website, a key piece of that information is an IP address: an address the browser can connect to.

Your browser or device usually asks a recursive resolver, a DNS service that does the lookup on your behalf. It may reuse a saved, or cached, answer. Otherwise, it follows DNS referrals to the authoritative nameserver that publishes the domain’s DNS records.

For illustration, imagine an A record, a DNS entry that supplies an IPv4 address, mapping example.com to 192.0.2.10. That address is reserved for documentation; this is an example, not a live lookup.

DNS lookupHTTPS requestAsk a resolver:example.comGet an address:192.0.2.10Request pagefrom the hostExample address, not a live result.

A simplified website visit. Looking up the address and fetching the page are separate operations.

DNS helps find the address. HTTPS requests the page. Moving the website’s files to a new host does not, by itself, change the DNS answer.

Why moving the site does not move DNS authority


The tempting mental model is simple:

I bought the domain from a registrar, so I configure the domain at the registrar.

That model is incomplete in a consequential way. Buying a domain and answering for a domain are separate responsibilities, and they are routinely held by different companies.

There are five responsibilities to keep separate. The registrar manages the registration; it is not a stop on every visitor’s DNS lookup:

  1. The registrar — where the domain is purchased and renewed.
  2. The delegation — a pointer in the parent zone naming the domain’s authoritative nameservers. For example.com, the parent zone is .com.
  3. The zone — the actual records, held by whoever the delegation names.
  4. The origin — the platform that serves the bytes.
  5. TLS and routing — certificate issuance and the relationship between the apex domain and www.

In this migration, the site was deploying to GitHub Pages, while recorded nameserver answers named the old DNS provider and HTTP requests reached the old host. Those observations show a path to investigate; the recursive nameserver answers alone do not prove the parent delegation was responsible.

The deploymentBuildsucceedsGitHub Pagessite readyDNS changesseparately.The visitor's routeDelegation:old providerOld DNS zone:old addressOld hostHTTP 404

A successful deployment does not change the DNS path visitors follow.

You do not have to move DNS providers when you move hosting: Vercel DNS can stay in place while GitHub Pages serves the site. If the DNS records need to change, update the zone whose answers visitors actually use.

Why the Control Panel Misleads You


Here is where the controls can mislead.

A registrar can offer both DNS-record editing and nameserver settings. These are different controls. If delegation selects another provider, editing a separate zone at the registrar will not change the public answers followed through that delegation. The registrar’s nameserver controls can still change the delegation.

In that situation, waiting for propagation or clearing caches does not fix editing the wrong zone.

The interface you are editing and the system that is consulted are not guaranteed to be the same system. Verify authority before you change configuration.

That sentence is the transferable lesson, and it is not really about DNS.

Trace the delegation first


Before changing anything, start with your recursive resolver’s view. In these commands, replace example.com with your domain:

dig +short NS example.com

This answer may be cached and may contain the child zone’s NS data. It does not establish the current delegation in the parent zone. Follow the referrals with +trace:

dig +trace NS example.com

For example.com, look for the referral from a .com parent nameserver naming example.com’s servers. That is the parent delegation evidence. The final NS answer from the child’s servers is the child zone’s own answer, not that referral.

During the original troubleshooting of raghib.io, the recorded NS answer was:

ns1.vercel-dns.com
ns2.vercel-dns.com

The site was deploying to GitHub Pages while that answer named Vercel DNS. That can be a valid arrangement. The active zone’s hosting records and the HTTP response needed separate checks.

The historical response from https://raghib.io/ included this status line and selected headers (excerpt, not complete output):

HTTP/2 404
server: Vercel
x-vercel-error: DEPLOYMENT_NOT_FOUND

Vercel documents DEPLOYMENT_NOT_FOUND as meaning that the requested deployment could not be found. These headers identify a Vercel response; they do not establish which DNS setting sent the request there.

Error messages help narrow the investigation:

SignatureWhat it tells you
DEPLOYMENT_NOT_FOUNDThe vendor received the request but could not find the deployment
“There isn’t a GitHub Pages site here”Pages is reachable but has no site for this hostname
Cloudflare error 1000Cloudflare blocked the request; investigate a prohibited target or other documented configuration causes
Cloudflare error 1016Cloudflare cannot resolve the origin hostname
NoSuchBucketThe requested bucket does not exist
NXDOMAINThe resolver reports that the queried DNS name does not exist
A certificate warningTLS certificate validation failed; inspect the hostname, chain, and validity dates

A response naming the old host tells you where the request arrived, not which DNS setting was wrong. Check parent delegation, the records in the selected zone, and cached answers. The nameserver result is a starting point, not a diagnosis on its own.

Do Not Trust Your Own Resolver


The second discipline matters as much as the first.

A record’s time to live (TTL) tells a resolver how long it can normally reuse a cached answer. During a migration, your own machine may keep returning an old answer consistently enough to look like evidence of a failed change.

Ask a confirmed authoritative nameserver directly. Here, example.com and ns1.example.net are placeholders for your domain and its authoritative server:

dig @ns1.example.net example.com A +norecurse

Check for the aa (“authoritative answer”) flag. The record’s TTL in that answer is the value the authority publishes, rather than a recursive cache’s remaining lifetime. If the authority publishes the new address but a resolver still returns the old one, check the cached answer’s remaining TTL before changing more configuration.

Authoritative zoneNew address (already changed)Resolver cacheOld addressstill cachedCached TTL expiresNext lookup:new address

Two different answers do not necessarily mean two broken systems. One may be current zone data; the other may be an unexpired cached answer.

Compare complete answer sets for the same name and record type, ignoring address order. Rotation can legitimately change the set, and location-based DNS (GeoDNS) can return different sets to different query locations. Check the provider’s expected behavior for those locations before treating a difference as stale DNS. Sorting answers or taking two samples cannot, by itself, establish a caching problem.

TTL Is One Part of the Blast Radius


Before a cutover, read the configured TTL from a known authoritative server. With the same placeholders:

dig @ns1.example.net example.com A +norecurse +noall +answer

The number after the record name is the TTL in seconds. A recursive resolver may instead show the remaining lifetime of a cached answer; do not assume that is the current configured TTL.

If a record’s TTL is a day, lowering it to 300 seconds does not shorten copies already cached for a day. Lower it before the migration, then wait for the old TTL to elapse before changing the address.

That reduces the normal caching window for that record to five minutes. It is not a five-minute guarantee for the whole cutover: parent-zone NS and DS records have their own TTLs, and negative answers can be cached for a duration derived from the zone’s SOA record. A lower address-record TTL does not speed up a nameserver change.

This is ordinary risk management expressed in infrastructure: reduce the cost of being wrong before you take the action that might be wrong.

What Actually Gets Lost


The website was the visible failure here. Other services can be affected by the same change, even if their failures are less obvious.

A zone can also hold mail routing, sender authentication, and domain-ownership proofs. If those records are missing from the destination zone, a delegation change can disrupt mail delivery, weaken sender authentication, or break service verification. These are possible risks, not losses established by this migration.

Before any cutover, account for:

  • Apex and www A, AAAA and CNAME records, plus provider-specific ALIAS, ANAME or flattening behavior where used
  • MX, SPF, DKIM, and _dmarc
  • Domain-verification records for every external service
  • Live subdomains such as api, staging, docs, and status
  • Existing CAA policy and whether it authorizes the destination’s certificate authority
  • DNSSEC signing state, DNSKEY data and parent-zone DS records; an incompatible DS record after a nameserver change can cause validating resolvers to return SERVFAIL (migration guidance)

Any item you cannot account for is a cutover risk to investigate before proceeding.

Encoding the Procedure


I wrote a local diagnostic script to make the nameserver lookup, public and direct DNS queries, HTTP checks, and carry-over inventory repeatable. That makes the procedure easier to rerun; its interpretations still need to be tested.

This selected excerpt preserves recorded nameserver and HTTP lines, with overbroad diagnostic conclusions omitted:

  nameserver             ns1.vercel-dns.com

  ✗ raghib.io — HTTP 404, served by Vercel
    x-vercel-error: DEPLOYMENT_NOT_FOUND

Those old conclusions were too broad. A registrar’s delegation controls still matter, and recursive NS results are not by themselves proof of parent delegation.

The checks also need to account for the address variation described above and for wildcards. A wildcard can supply answers for otherwise absent names, but existing names and delegation boundaries limit where it applies. That can make naive enumeration mistake wildcard answers for explicitly configured names.

Scripts and checklists both encode assumptions. Make the checks repeatable, then test those assumptions against known-good cases and deliberate test failures.

What Changed During Troubleshooting


During troubleshooting, I changed the nameserver setting to Namecheap BasicDNS and corrected an A-record typo: 85.199.108.153 became 185.199.108.153. Because both the nameserver setting and records changed before the later observation, this does not isolate which change caused the earlier failure.

Separately, the earlier troubleshooting reply recorded:

  • Nameservers: dns1.registrar-servers.com and dns2.registrar-servers.com.
  • Apex A records: 185.199.108.153, 185.199.109.153, 185.199.110.153, and 185.199.111.153.
  • www CNAME: ragmha.github.io.
  • HTTP 200; TLS provisioning was still pending, and no successful HTTPS response was recorded.

Those are recorded historical observations, not fresh checks. They establish neither which change fixed the HTTP response nor a completed HTTPS cutover.

The General Case


Strip away the protocol and a reusable pattern remains, applicable to any system where configuration and authority can drift apart:

  1. Establish who is authoritative before changing configuration. The editable surface may affect the consulted system indirectly; confirm that relationship.
  2. Read the error vocabulary precisely. A 404 from the old host and one from the new host tell you different things about where the request arrived.
  3. Distrust your own cached view. Compare it with the responsible source, accounting for caching and legitimate answer variation.
  4. Reduce the blast radius before acting, not after the incident.
  5. Inventory the invisible dependencies. The visible failure may not reveal every service at risk.
  6. Encode the procedure so its assumptions can be tested and corrected.

Feature flags, identity and access policies, caching layers, service discovery, and configuration management can show the same pattern: a successful edit in one system does not necessarily change the system being consulted.

The durable habit is narrow enough to state in a sentence: before changing a configuration, confirm how that setting affects the system being consulted.


← All writing