Technical SEO Web Development

404, 410, or Redirect? What to Do With Pages You Delete

Published

Deleting a page is easy. Telling the web what happened to it is where sites get it wrong, usually by bulk-redirecting everything to the homepage. Here is a decision tree, the real difference between 404 and 410, and why a soft 404 is the worst of all options.

Every site accumulates dead pages. Products get discontinued, campaigns end, that 2019 microsite finally gets put out of its misery. The deletion is the easy part. What breaks sites is the next decision, and there is one wrong answer that is weirdly popular: redirect every dead URL to the homepage and call it tidy. It is not tidy. It actively confuses search engines and irritates the humans who clicked a link expecting a product.

The decision tree

Is there a page that genuinely replaces this one?
  |
  |-- YES: does it answer the same question the
  |        old URL answered?
  |          |
  |          |-- YES  -> 301 to that page
  |          |
  |          '-- NO   -> 404 / 410
  |                     (a loosely related page is
  |                      not a replacement)
  |
  '-- NO: is it coming back?
            |
            |-- YES, soon        -> keep it, or 503
            |                       with Retry-After
            |
            |-- NO, but it might -> 404
            |
            '-- NO, never        -> 410

The branch people get wrong is the second one. "Is there a replacement?" gets answered yes far too often. A discontinued blue widget redirecting to the red widget is helpful. A discontinued blue widget redirecting to /products is a coin flip. A discontinued blue widget redirecting to the homepage is neither helpful nor honest, and Google may treat that kind of irrelevant redirect as a soft 404 anyway — so you get the downside of a 404 plus the downside of hiding it.

404 versus 410

Both mean the page is not there. The difference is certainty:

  • 404 Not Found — "there is nothing here." Says nothing about whether there ever was, or whether there will be.
  • 410 Gone — "there was something here, it is deliberately gone, and it is not coming back."

Google treats them almost identically. Both lead to the URL being dropped from the index. Google has said 410 is acted on marginally faster, because 404 carries an implicit "maybe this is a mistake, I will check again later." That is the honest size of the difference: small.

So use 410 when you are certain and it costs you nothing to say so — a retired product line, a deleted user account, an expired campaign. Use 404 as your default, because most of the time you are not certain, and 404 is the code the whole web already handles gracefully.

What matters far more than picking between them is that you send one at all.

Soft 404: the actual problem

A soft 404 is a page that says "not found" in the body while the HTTP response says 200 OK. Humans read the words and understand. Machines read the status code and conclude they have found a perfectly good page, so they index it, keep recrawling it, and treat every dead URL as real content.

What the visitor sees:  "Sorry, this page doesn't exist"
What the crawler sees:  HTTP/1.1 200 OK   <- a real page!

This happens most often with client-side routing. The server returns index.html with a 200 for every path, the JavaScript router figures out the route is unknown, and it renders a "not found" view. The status code was decided before your router ever ran. If your app does this, the route table needs to live somewhere the server can consult, or you need server-side rendering for at least the 404 case.

Google reports these under "Soft 404" in Search Console, and it is worth checking, because the list is often full of URLs nobody knew were broken.

Verify what you actually send

A beautifully designed 404 page proves nothing about the status code behind it. Ask:

curl -o /dev/null -sw '%{http_code}\n' \
  https://example.com/this-page-does-not-exist
# want: 404
# a 200 here is a soft 404

Run it against a URL you know is dead, and against a URL that looks plausible but is not, like a mistyped product slug. Frameworks sometimes handle the first case correctly and the second case not at all.

Apache rules

A whole retired section, gone for good:

RewriteEngine On

# [G] sends 410 Gone
RewriteRule ^old-shop/ - [G]

# Or without mod_rewrite:
RedirectMatch 410 ^/campaigns/summer-2024/

# Custom pages, still returning the right status
ErrorDocument 404 /errors/404.php
ErrorDocument 410 /errors/410.php

A subtlety with ErrorDocument: point it at a path, not a full URL. Give Apache an absolute URL like https://example.com/404 and it issues a redirect to that page, which turns your 404 into a 302 followed by a 200. That is a soft 404 built by accident, and it is a common one.

And make sure your error document does not itself return 200. In PHP that means the handler needs to set the status explicitly if it is reached directly:

<?php
http_response_code(404);
// then render the page

Our .htaccess generator covers the redirect and status-code blocks, including 410, with the syntax already right — useful because RedirectMatch and RewriteRule take their arguments in an order that is very easy to misremember.

The case for keeping it alive: 503

If a page is temporarily unavailable — a maintenance window, a supplier feed that is down, stock you expect back next week — do not 404 it. Say so:

HTTP/1.1 503 Service Unavailable
Retry-After: 3600

503 means "come back later," and crawlers respect that: they retry rather than starting the removal process. Retry-After takes seconds or an HTTP date. This is the correct response for a planned deploy window too, and it is much better than serving a broken page with a 200.

The one thing not to do is leave a 503 up for weeks. A long-running 503 eventually gets treated as a real outage, and crawl rates drop across the site.

What about 403 and 451?

403 Forbidden means "this exists and you may not have it." It is the right code for a permissions boundary, and the wrong code for content you removed. Crawlers will eventually stop showing a 403 URL, but you have told them nothing useful about why.

451 Unavailable For Legal Reasons is real, standardized in RFC 7725, and it is the honest answer when content is pulled because of a legal demand rather than an editorial decision. Rarely needed. Genuinely satisfying when it is.

Recurring 404s in Search Console are fine

One last piece of reassurance, because this generates a lot of needless anxiety. Google will keep requesting a deleted URL for a long time after it is gone, and Search Console will keep listing it. That is not a penalty and not a problem to fix. Crawlers retry because URLs come back sometimes. A 404 that is supposed to be a 404 is working correctly.

The report is worth reading, though, for a different reason: if a 404 has internal links pointing at it, that is a broken link on your own site. Fix the link, not the status code.

The summary

  • Real replacement exists: 301 to it. One hop, and it must genuinely answer the same question.
  • No replacement: 404. This is fine and normal.
  • Gone deliberately and permanently: 410, if you feel like being precise.
  • Temporarily away: 503 with Retry-After.
  • Never: a 200 that says "not found," or a bulk redirect to the homepage.
  • Always: verify with curl, because the page design and the status code are unrelated facts.

More reading