Twelve SEO own goals, two of them mine
Most SEO disasters aren't clever. They're one line in one file, left in the wrong state for weeks. Here are twelve I've seen. Two of them are mine. I'll let you guess which.
1. Canonicals pointing at the wrong host
The site ran on www. Every canonical tag pointed at the non-www version. Search Console listed eight pages as "Alternative page with proper canonical tag" and indexed two. It was found around six months after launch, by which point the site had no clicks and six impressions to show for itself. It's an easy one to miss when you're busy getting a site off the ground.
Google was doing exactly what it was told: treating every page as a copy of somewhere else. The fix was to put canonicals, the sitemap, internal links and structured data on the same host, with one 301 for everything else.
How to catch it: run URL Inspection in Search Console and compare the user-declared canonical with the URL you're inspecting. If they differ, find out why. A crawler will list the mismatched canonicals. What matters is checking them against your Search Console data to see which pages aren't indexed and what traffic isn't arriving.
2. An .htaccess file without its dot
Apache only reads a file called .htaccess. Save it as htaccess, which is easy when your computer hides dotfiles or an upload tool renames it, and it's just a text file. Every redirect in it does nothing and nothing warns anyone.
How to catch it: request an old URL and check you get a 301 to the right place. Don't assume a file works because it's on the server.
3. noindex and nofollow left on after launch
A developer adds noindex, nofollow to the staging site, rightly. The site goes live and nobody takes it off. Pages fall out of the index over the following days and weeks and links stop passing anything.
How to catch it: crawl the live site on launch day and filter for noindex and nofollow. Check the X-Robots-Tag HTTP header as well as the meta tag, because it can hide there.
4. The staging robots.txt goes live
User-agent: * then Disallow: /. The whole site is blocked from crawling. Pages already indexed can linger as bare URLs with no description, which looks almost worse than vanishing.
How to catch it: open /robots.txt on launch day. It takes ten seconds.
5. WordPress's "Discourage search engines" box left ticked
Settings, Reading, one tickbox. It tells search engines to stay away from every page. It's ticked during the build and forgotten at launch.
How to catch it: same as number 3. Crawl on launch day.
6. A migration with no redirect map
New platform, new URL structure, no redirects. Every old URL returns a 404, every backlink points at nothing and rankings built over years go with them.
How to catch it: before launch, list every old URL from a crawl, Search Console, analytics and your backlink data. Map each one to its closest new page. After launch, check them all again. If one's coming up, this is how I handle migrations. A list of 404s tells you something broke. Checking each one against the traffic and links it used to have tells you which ones to fix first.
7. 302s where 301s were meant
A 302 says the move is temporary and the old URL may come back. Google does eventually treat a long-standing 302 like a 301, but it's slower and you're relying on its judgement instead of telling it plainly.
How to catch it: check the status code, not just that the redirect lands somewhere.
8. Redirect chains
Old page to newer page to newest page. Every hop slows things down and Google stops following after ten. Chains build up quietly over several migrations.
How to catch it: crawl your list of old URLs and point every one straight at its final destination.
9. noindex behind a robots.txt block
You want a page out of Google, so you add noindex and block it in robots.txt. Google can't crawl the page, so it never sees the noindex. The URL can stay indexed indefinitely.
How to catch it: let Google crawl the page until it drops out. Block it afterwards if you need to.
10. Tracking that breaks itself
Two versions of the same mistake. UTM tags on internal links overwrite how GA4 attributes the visit, so a paid visitor becomes a visitor from your own homepage. Redirects that strip query strings do the reverse: paid traffic arrives with no tags and shows up as Direct.
How to catch it: never tag internal links. Click your own ads and check the landing URL still has its parameters.
11. The analytics tag missing from the new template
The GA4 code lived in the old site's header. The new theme doesn't have it, or has it on some templates and not others. Nobody notices until the monthly report shows a cliff.
How to catch it: on launch day, open one page of every template type and check it appears in GA4's real-time report.
12. Staging left open
A full copy of the live site sits at staging.yoursite.com, open to anyone and indexed. Now Google has two of everything and has to guess which is real.
How to catch it: password-protect staging. noindex alone isn't enough, because someone will eventually copy it to live.
Spotting it isn't the same as understanding it
Every one of these takes seconds to cause and weeks to undo. Most crawlers will flag them. You get a list: 40 redirect chains, 12 noindexed pages, 300 404s. What a list doesn't tell you is which ones matter. A noindex on a page nobody visits is housekeeping. A noindex on your best-selling category is an emergency.
That's why I don't stop at the list. A custom crawler finds the problems that can then be checked against Search Console/Bing Webmaster/Server Logs & any other data: which pages dropped out of the index, what traffic and links they used to have and which other issues sit behind them. Twelve separate findings usually turn out to be two or three causes. Fix those and the rest follow.
