The Domain Control Center answered Domain not found. Our own build runbook had told us to flip an apex A record in a specific GoDaddy reseller account, and the registrar disagreed with it before we edited anything.

We wrote that runbook. It wasn’t stale documentation from a departed engineer. It was a fresh build doc for an in-progress migration, and it had already drifted from reality. A runbook is a hypothesis about state. It is not state.

The setup

We were migrating a batch of domains to a new DNS layout. Part of that is standing up an off-origin Caddy relay, a tiny DigitalOcean box that auto-issues a Let’s Encrypt cert and 301s the bare apex to www. The final step for each domain is repointing its apex A record at the relay’s IP. The runbook said, in effect, “apex for example.com lives in the reseller portfolio, go edit it there.”

So we logged into the reseller SSO, opened the Domain Control Center, searched for the domain, and got the “Domain not found” result.

There are two moves at that point, and only one is fine. You can stop and work out why the registrar disagrees with your doc. Or you can hand-wave it (“must be a search glitch, check the other view”) and keep going. The wrong move feels faster, and it isn’t.

The contradiction was already in our own notes

We didn’t have to guess. We keep a .secrets/godaddy.env with account notes, because GoDaddy spreads our domains across more than one login. Those notes said this domain was not in the reseller account at all. It was in our personal customer account, whose credentials were in the same secrets file.

So the runbook said the reseller account, the notes said the personal account, and the registrar said “not found” for the first one. That is three sources, and the two we could check agreed against the runbook.

The fix was self-serve and took thirty seconds. We logged out of the reseller SSO, signed in with the stored personal-account credentials, landed on the right portfolio, and there was the domain. Nobody needed to be asked. If we had trusted the runbook and pushed harder to find the record in the reseller account, the best case was wasted time. The worst case was editing a different domain’s zone because something matched loosely, and on live DNS that takes customer sites down.

The forwarding lock

Once we were in the right account, the apex wasn’t a normal A record. It was GoDaddy’s HTTPS-forwarding setup: two anycast A records, the provider’s documented forwarding front-ends, both marked Can’t edit / Can’t delete.

The records look like targets you should overwrite, and the UI won’t let you touch them. The way through is to delete the forwarding entry first, meaning the 301 forwarding rule and not the A records. Deleting it collapses the two locked anycast records into a single editable A @ pointing at Parked. Then you can set that one record to the relay IP. TTL was 600.

This generalizes past GoDaddy. When a registrar hands you records you can’t edit, look for the higher-level feature that owns them (forwarding, a managed redirect, a CDN integration). The editable record is on the other side of disabling that feature, so don’t fight the lock directly.

The propagation read that almost lied to us

After we set the apex to the relay IP, we checked propagation. Google Public DNS returned the new IP within seconds. Had we stopped there, we would have called it converged and moved on.

But the authoritative nameservers for the zone, ns17 and ns18.domaincontrol.com, were still handing back GoDaddy’s forwarding anycast fleet, the AWS-hosted front-ends the old setup pointed at. Propagation was mixed. Google Public DNS had either cached nothing for that name or pulled from an edge that updated early, and the source of truth hadn’t caught up.

That matters because of the next step in the migration. The relay uses Let’s Encrypt on-demand TLS, and its http-01 challenge does its own DNS lookup on its own schedule, whatever resolver we happened to check with. If we had trusted the popular public resolver and kicked off issuance, the challenge could have hit a host still pointing at the old forwarding. We’d have spent twenty minutes debugging a “cert won’t issue” problem that was just an unconverged zone.

The correct read is dig @ns17.domaincontrol.com example.com. Ask the source of truth, wait until both authoritative servers return the relay IP, and then trigger issuance.

Google Public DNS tells you what one popular resolver currently believes. It doesn’t tell you whether your change is live at the zone, and for anything downstream that validates against authoritative servers, its answer is noise.

Three misreadings in ten minutes

Three things went wrong-adjacent in one ten-minute window, and all three are the same mistake in different clothes.

  • The runbook represented which account held the domain. The registrar held the truth, and they disagreed.
  • The forwarding A records represented the apex. The forwarding feature owned them, and you can’t edit the representation without addressing the owner.
  • A public resolver represented propagation. The authoritative nameservers held the answer, and they lagged.

So before any live-DNS edit, this is what we do now:

  1. Confirm which account and zone actually holds the record at the registrar. Search for it. If the registrar says “not found,” believe the registrar over your doc and go find where the domain lives before you touch anything.
  2. If records won’t edit, find the feature that owns them (forwarding, redirect, managed integration) and disable that first.
  3. Read propagation at the authoritative nameservers rather than a public resolver like Google’s, especially when anything downstream (ACME, an SSL validator, a partner’s resolver) checks the source of truth. Wait for all of the zone’s NS records to agree before you call it done.

The five seconds it takes to confirm current state against an authoritative source (the registrar, the NS records, the actual API) is the cheapest insurance you can buy on a live system. We write the runbooks and we still verify against the registrar every time. The version of us that wrote the doc was working from a snapshot, and the snapshot expired.