← Writing

The shop whose DNS pointed at a dead server for a year

A while back I took over a small online shop that had been quietly broken for about a year. Not down. Broken. The homepage loaded. The catalog loaded. Checkout worked. And roughly a third of the people who typed the domain into their browser got a connection timeout, then went somewhere else.

The owner's description was "the site is slow sometimes." That is almost always what this sounds like from the inside, because the person who reports it is the person whose computer happens to be resolving to the half of the answer that still works.

Two A records, one dead server

The domain had two A records. One pointed at the current host. The other pointed at an IP that had belonged to a previous hosting account, canceled about fourteen months earlier. That IP had long since been recycled to somebody else, and whatever was there now dropped packets on port 443 rather than answering.

Round-robin DNS does not know any of this. A resolver picks an address, hands it to the browser, and the browser tries it. If it works, you have a fast site. If it does not, you have a spinner and then an error page, and the customer does not know it is a DNS problem because nobody outside this trade knows that DNS is a thing. They know your shop didn't load.

Uptime monitoring did not catch it either, because the check was configured against the working IP. The site was "100% up" for the entire year it was half broken.

How it got there

Nobody did anything stupid. A developer added the second record during a migration years earlier so that the old and new servers would both answer while DNS propagated. That is a reasonable thing to do for a day. Then the migration finished, the developer's engagement ended, and the record stayed. Every subsequent change went into the same zone: a new MX, a TXT record for a marketing tool, a CNAME for a subdomain. Nobody looked up two lines.

That is the shape of almost every DNS incident I get called into. Not a bad decision, an unfinished one.

What it actually cost

We only got a real number because the shop had a year of analytics and card-processing history sitting there. Sessions were flat, but the ratio of sessions to unique visitors was ugly, and direct traffic had a bounce profile that looked nothing like organic. The owner's read of it was that they had plateaued and needed to spend more on ads. They had been doing exactly that, into a front door that failed one time in three.

I am not going to dress that up with a precise revenue figure, because attribution over a year that messy is guesswork. The honest version: the fix was one DNS record deletion, it took less time than writing this paragraph, and it had been costing more per month than every service I sell combined.

The five-minute version of this check

You do not need a tool for this. On any machine:

Resolve your domain and look at how many addresses come back. If there is more than one, you should be able to say out loud what each one is for. If you cannot, that is the whole finding.

Then hit each address directly over HTTPS and confirm each one serves your site. An address that times out, refuses the connection, or serves somebody else's certificate is a live bug with your name on it, not a leftover.

Do the same for anything you have pointed elsewhere: a shop subdomain, a booking page, a mail record, a status page. Old CNAMEs pointing at canceled SaaS accounts are the same failure with a different hat on, and they are worse, because someone else can often claim that abandoned hostname and serve whatever they like from your subdomain.

Where this sits in what I do

This is why the domain and DNS layer is inside the plan rather than billed as a project. Hosting is $49 a month, Care is $149 with changes handled, and a store starts at $249. Under those, DNS and domains are simply looked after, because a stale A record is not a project. It is a thing somebody has to notice, and noticing is what the monthly number pays for.

If you would rather do it yourself, do the resolve-and-hit-each-address check above once a quarter and after every migration. Delete the record you added for propagation as the last step of the migration, not "later." And point your uptime monitor at the hostname rather than an IP, so it exercises the same path your customers do.

The site that is down gets fixed the same day, because everyone can see it. The site that is down for a third of people stays broken for a year.


Need this kind of thinking applied to your own setup? Get in touch →