Technical SEO MasteryStatus codes, redirects, canonicals and duplicate URLs · Lesson 6 of 18

Status codes, redirects and soft 404s

Article · 14 min · 8 min lecture

Video lecture

Status codes, redirects and soft 404s

13 chapters · about 8 min · full transcript

Coming soon

Chapter 1 of 13

Status codes, redirects and soft 404s

  • What each code tells Google
  • Choosing the right redirect
  • Chains, loops and soft 404s

The narrated lecture is in production

Every chapter is scripted and ready. Browse the chapters and read the full transcript now — the video will appear here when it’s published.

Chapters

Status codes are instructions

Search engines read the HTTP status code before anything else. Getting it right is one of the highest-leverage technical fixes because it tells Google what to do with the URL and its signals.

CodeMeaningWhat Google does
200OKContent eligible for indexing
301Moved permanentlyStrong signal that the target should be canonical
308Permanent redirect (method preserved)Treated like 301
302 / 307Temporary redirectWeak canonical signal; source may stay indexed. If it persists, Google may treat it as permanent
304Not modifiedReuses the previously fetched content
404Not foundURL dropped from index over time; no penalty for having 404s
410GoneSimilar to 404; may be processed slightly faster
429Too many requestsTreated like a server error; slows crawling
500 / 503Server error / unavailableCrawling slows; prolonged errors can drop URLs

Key insight: 404s are normal and healthy for content that no longer exists. The problem is 404s on URLs that should exist, or with valuable backlinks pointing at them.

Choosing the right redirect

  • Permanent move (URL change, HTTPS, domain move, merged content): 301 or 308.
  • Temporary (short promotion, maintenance on a specific page, geo or A/B test where the original should stay canonical): 302 or 307.
  • Planned downtime: 503 with a Retry-After header, not a redirect to a maintenance page returning 200.
  • Avoid: meta refresh and JavaScript redirects when a server redirect is possible. Google can follow them, but they are slower and weaker signals.
# Nginx: single-hop redirects
server {
  listen 80;
  server_name example.com www.example.com;
  return 301 https://www.example.com$request_uri;
}
location = /old-guide { return 301 /guides/new-guide; }
# Apache .htaccess
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
Redirect 301 /old-guide /guides/new-guide

Redirect chains and loops

A chain is A → B → C. Google documents following up to 10 hops, but every hop costs crawl resources, adds latency for users, and adds risk. Best practice:

  1. Redirect every legacy URL directly to its final destination (one hop).
  2. Update internal links, canonicals, hreflang and sitemaps to point at final URLs, so users and bots rarely hit redirects at all.
  3. When you add new redirects, rewrite older ones that point at the now-redirected URL.

A quick chain check:

curl -sIL https://example.com/old-page | grep -Ei "^(HTTP|location)"

Redirect mapping principles

  • Map to the most relevant equivalent, not the home page. Mass-redirecting unrelated URLs to the home page is typically treated as a soft 404.
  • If there is no equivalent, a 404/410 is honest and acceptable.
  • Keep redirects in place long term — Google's migration guidance suggests at least a year, and many practitioners keep them indefinitely because external links persist.

Soft 404s

A soft 404 is a URL that returns 200 but looks like an error or empty page: "No products found", "This item is unavailable", a thin template with no main content, or an irrelevant redirect. Search Console reports these in Page indexing.

Fixes by cause:

CauseFix
Deleted product showing "not found" with 200Return 404/410, or 301 to a close replacement
Empty category/filter resultsReturn 404, or noindex and remove internal links to it
Out-of-stock productKeep 200 if it will return, with useful content (alternatives, restock date); avoid thin "unavailable" pages
SPA error viewServer 404 or JavaScript-injected noindex
Redirect to irrelevant pageRedirect to a relevant page or return 404

Worked example 1: 12,000 discontinued products

A UK retailer's audit finds 12,000 discontinued product URLs returning 200 with "Sorry, this product is no longer available". Some have backlinks. The plan: pull backlink data and Search Console clicks for each URL; 301 those with links or traffic to the closest current product or the parent category (only where genuinely relevant); return 410 for the rest; remove them from sitemaps and internal links; monitor the soft 404 count trending down in Search Console.

Hands-on: a redirect chain and status checker

# pip install requests
import csv, sys, requests

def trace(url, max_hops=10):
    hops, current = [], url
    for _ in range(max_hops):
        r = requests.head(current, allow_redirects=False, timeout=15,
                          headers={"User-Agent": "Mozilla/5.0 (compatible; audit-bot)"})
        if r.status_code in (405, 501):          # some servers reject HEAD
            r = requests.get(current, allow_redirects=False, timeout=15, stream=True)
        hops.append((current, r.status_code))
        loc = r.headers.get("Location")
        if r.status_code in (301, 302, 303, 307, 308) and loc:
            current = requests.compat.urljoin(current, loc)
            if current in [h[0] for h in hops]:
                hops.append((current, "LOOP")); break
        else:
            break
    return hops

w = csv.writer(sys.stdout)
w.writerow(["start", "final", "final_status", "hops", "types", "problem"])
for url in (l.strip() for l in open("urls.txt") if l.strip()):
    h = trace(url)
    types = [str(s) for _, s in h[:-1]]
    final, status = h[-1]
    problem = ("loop" if status == "LOOP" else "chain" if len(h) > 2 else
               "temporary" if any(t in ("302", "307") for t in types) else
               "error" if isinstance(status, int) and status >= 400 else "")
    w.writerow([url, final, status, len(h) - 1, "|".join(types), problem])

Run it on legacy URLs, internal links pointing at redirects, and backlink targets. Anything flagged chain, loop, temporary (for a permanent move) or error goes into a ticket with the correct single-hop destination.

Worked example 2: a Gulf retailer's maintenance page

A Doha electronics retailer (illustrative) takes its store offline for a four-hour platform upgrade and redirects every URL with a 302 to /maintenance, which returns 200. Afterwards, Search Console shows spikes in soft 404s and some product URLs temporarily replaced by the maintenance page in results. The better pattern for next time: return 503 with a Retry-After header on the original URLs during maintenance, keep the window short, and never serve a 200 "we'll be back" page in place of real content.

Common mistakes

  • Using 302s for permanent moves because it is the platform default (check your CMS or plugin).
  • Redirecting everything to the home page.
  • Custom error pages that return 200.
  • Letting redirect rules pile up for years without flattening chains.

Key takeaways

  • Use 301/308 for permanent moves, 302/307 for temporary, 503 plus Retry-After for maintenance.
  • Redirect legacy URLs in a single hop to the most relevant equivalent, then update internal links to the final URL.
  • 404 and 410 are healthy for genuinely gone content; mass home-page redirects become soft 404s.
  • Soft 404s are 200 responses that look empty or erroneous — fix the status code or the content.

Check your understanding

Quick questions to lock in the lesson. They don’t count towards your certificate.

  1. A site is down for four hours of planned maintenance. What should it return?
  2. You retire 300 blog posts with no equivalent content and no backlinks. Best response?
  3. Which is a soft 404?

Put it into practice

Run a crawl, export all 3xx URLs with their redirect chains, and produce a flattened one-hop redirect map for the worst ten chains.

Enrol for free to save your progress

Reading is always free. Enrol to keep your place, take the final assessment and earn a verifiable certificate.