HTTP status codes are three digit numbers your server sends with every response: 200 means the page is fine, 301 means it moved for good, 404 means it doesn't exist, 5xx means the server itself failed. Google reads these codes on every crawl and acts on them, deciding what gets indexed, what gets dropped, and how hard your site gets crawled at all. Most of the codes never matter for SEO. About eight of them decide a lot, and this guide covers exactly those.
The stakes are asymmetric. The right code is invisible; nobody praises your 301. The wrong one quietly removes pages from Google or fills your index with junk, and the traffic graph is usually how you find out. The good news: the whole system is checkable with one terminal command and one Search Console report.
The Five Classes at a Glance
The first digit sorts every code into one of five families, and that digit alone tells you most of what Google will do next. The full picture lives in Google's HTTP status codes documentation, which this guide quotes throughout:
| Class | It means | What Google does |
|---|---|---|
| 1xx Informational | Handshake in progress | Nothing you'll ever act on for SEO |
| 2xx Success | The request worked | Passes the content onward toward indexing |
| 3xx Redirection | The answer lives at another URL | Follows the hop, up to 10 in a chain |
| 4xx Client error | The URL is wrong, gone or off-limits | Treats the content as nonexistent, drops it from the index |
| 5xx Server error | Your server failed to answer | Slows crawling, and drops pages if the errors persist |
Two families do the real work. Everything interesting in SEO happens in the 3xx and 4xx rows, plus one success code that lies. The rest of this guide walks through them in the order you'll meet them on a real site.
200: Success, Not a Promise
A 200 says the server delivered the page. That's all it says. Google's documentation is precise here: on a 2xx response, Google "considers the content for processing". Considers. A 200 gets you into the pipeline; it doesn't get you indexed. If your pages return 200 and still don't show up in Google, the problem lives further down the pipeline, and my indexing guide walks through all fifteen reasons.
The 200 rule that actually bites people is the inverse: only real, useful pages should return it. When your error page, empty search result or "product no longer available" notice answers with 200, you've created a soft 404, which gets its own section below. And your sitemap should contain nothing but 200 URLs; every redirect or dead link in there burns crawler trust.
Redirects: 301, 302, 307 and 308
A redirect answers "the page you want is over there". The SEO question is whether the move reads as permanent or temporary, because Google's redirect documentation treats the two differently: a permanent redirect is "a signal that the redirect target should be canonical", meaning the new URL inherits the old one's place, while a temporary redirect keeps the old URL in the results and inherits nothing.
| Code | Meaning | Google's treatment |
|---|---|---|
| 301 | Moved permanently | Strong signal: target becomes canonical, signals consolidate there |
| 308 | Moved permanently, stricter about request methods | Same as 301 |
| 302 | Found, temporarily elsewhere | Weak signal: source URL stays in results |
| 303 / 307 | Temporary variants | Treated like 302 |
The decision is simpler than the table: permanent move, 301. Genuinely temporary situation (an A/B test, a seasonal swap, a page briefly parked), 302. The classic mistake is shipping a migration on 302s because that's what the platform defaulted to, then wondering why the old URLs still rank while the new ones sit ignored.
Three rules keep redirects from leaking value:
- One hop. Googlebot follows up to 10 redirect hops, but every hop past the first is waste. Migrations stack: http to https, non-www to www, old slug to new slug, and suddenly one click triggers four redirects. Point everything at the final URL directly.
- Like for like. Redirect each old URL to its closest matching replacement. Google's site move documentation warns against pointing many old URLs at "one irrelevant single URL destination, such as the home page", which "might be treated as a soft 404 error".
- Leave them running. Google recommends keeping redirects live "generally at least 1 year", and indefinitely if users still follow old links. Redirects aren't scaffolding you tear down after launch week.
This site practices what it preaches: when I retired the old /seo landing page, its content was folded into the homepage, so its URLs 301 there, which is the consolidation case Google explicitly allows. The redirects stay live indefinitely because old ad clicks and bookmarks keep arriving. Server-side redirects are also the only kind worth trusting: Google interprets meta refresh and JavaScript redirects when it can, but its own documentation ranks them below a proper server response.
# Permanent move, one hop, like for like
Redirect 301 /old-guide/ https://example.com/new-guide/
# Deleted for good, no replacement exists
Redirect 410 /discontinued-product/
404 vs 410: Pages That Are Gone
A 404 says "not found". A 410 says "gone, and on purpose". Google's handling of both is identical in the way that matters: URLs returning either code are dropped from the index, and Google's documentation states plainly that already-indexed URLs returning 4xx "are removed from the index".
The 404 vs 410 debate has consumed years of forum arguments, so here's Google's John Mueller settling it in 2024: "The difference in processing of 404 vs 410 is so minimal that I can't think of any time I'd prefer one over the other for SEO purposes." In the same thread: "Google does not penalize for 404's (those pages drop out of the index though)." That echoes Google's own position since 2011: 404 errors don't hurt your site's ranking.
So when should you care about a 404? Ask what the URL was worth:
- The page had rankings, traffic or backlinks. A 404 here is a real loss; everything the page earned evaporates. If a genuine replacement exists, 301 to it. If not, accept the 410 and move on.
- The URL never existed. Typos, scraper guesses, broken external links to pages you never published. A 404 is the correct, healthy answer. Chasing a zero-404 report is chasing a number Google doesn't care about.
- The page is gone and has no replacement. Return 404 or 410 and let it drop. Do not redirect it to the homepage; you read what Google calls that in the previous section.
Soft 404s: The Success Code That Lies
Google's definition: a soft 404 is "a URL that returns a page telling the user that the page does not exist and also a 200 (success) status code". The content says dead, the code says alive, and Google believes the content. Search Console flags these as "Soft 404" in the page indexing report, and the affected URLs don't get indexed.
Why it matters beyond the flagged URL: per Google's docs, a success code on a nonexistent page means "search engines will continue trying to crawl that non-existent URL instead of spending time crawling your real pages". On a big site, thousands of soft 404s quietly eat the crawl capacity your real pages needed.
Where they come from, in the order I find them on audits:
- Custom error pages returning 200. The designer built a lovely 404 page; the server serves it with a success code.
- JavaScript sites. The server sends a 200 shell for every route and the app renders "not found" client-side. Every dead URL on the site is now a soft 404.
- Empty states. Category pages with zero products, search results with zero hits, expired listings that keep their URL.
- Homepage redirects. Dead URLs mass-redirected to the homepage, which Google may classify as soft 404s because the destination has nothing to do with the request.
The fix follows the content. Gone for good: return a real 404 or 410. Moved or replaced: 301 to the replacement. Thin but legitimate: make the page worth indexing, or noindex it (my meta tags guide covers the directive). Then verify with URL Inspection, because the report only updates after a recrawl.
The Quiet Ones: 304, 401, 403 and 429
Four codes you'll meet in crawl logs and Search Console that rarely need action, and one that does:
| Code | Name | SEO meaning |
|---|---|---|
| 304 | Not Modified | Healthy. Your server told Google the page hasn't changed since the last crawl, saving everyone bandwidth |
| 401 | Unauthorized | Google treats the content as nonexistent. Correct for genuinely private pages, fatal on public ones |
| 403 | Forbidden | Same treatment as 401. Often a firewall or bot protection blocking Googlebot by mistake |
| 429 | Too Many Requests | The exception in the 4xx family: Google reads it as "server overloaded" and slows crawling, like a 5xx |
The one that does need action is 403, because it's almost never intentional. CDNs and security plugins ship rules that challenge or block datacenter traffic, Googlebot crawls from datacenters, and suddenly your pages are "Blocked due to access forbidden" in Search Console while looking perfectly fine in your browser. If indexed pages start dropping and you never touched them, check what your firewall serves to Googlebot before you check anything else.
5xx: When the Server Itself Fails
Server errors trigger a different reflex in Google than dead pages do. Per the documentation, 5xx and 429 errors "prompt Google's crawlers to temporarily slow down with crawling", and URLs that keep erroring are eventually dropped from the index. Google backs off to protect your server, which is polite, but it means a flaky server gets crawled less, indexed less, and refreshed less.
Two 5xx situations are worth engineering deliberately:
- Planned maintenance gets a 503. A 503 Service Unavailable with a
Retry-Afterheader says "temporary, come back later" in the language crawlers speak. Your rankings ride out a few hours of 503 without drama. A maintenance page returning 200 risks having "We'll be right back" indexed as your content. - Robots.txt must never 5xx. A server error on that one file halts crawling of your entire site for 12 hours, and the details are ugly enough that my robots.txt guide gives them a full section.
# Everyone gets a 503 except your own IP
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^198\.51\.100\.7$
RewriteRule .* - [R=503,L]
ErrorDocument 503 /maintenance.html
Header always set Retry-After "3600"
If 5xx errors show up in Search Console's crawl stats without any deploy or outage you know about, the usual suspects are an overloaded shared server, a PHP error on a specific template, or a rate limiter counting Googlebot as an attacker. The crawl stats report tells you which URLs and when; your server's error log tells you why.
Which Code Should This URL Return?
Describe the situation, get the right status code. Runs entirely in your browser.
Permanent move, permanent redirect: the target inherits the old URL's signals. One hop, like-for-like destination, and update your internal links so they skip the redirect entirely. Keep it live for at least a year.
The old URL stays in search results, which is what you want if it's coming back. If "temporary" quietly becomes permanent, upgrade the redirect to a 301 so signals consolidate on the real page.
Both codes remove the page from the index, and Mueller says the difference is negligible. What matters: don't redirect it to your homepage. Google's docs warn that gets treated as a soft 404, and users hate it too.
A URL that never existed should say so. Google doesn't penalize 404s, and "fixing" them by redirecting garbage URLs somewhere real just teaches crawlers to keep requesting garbage. Make the 404 page helpful for humans and move on.
The crawler-speak for "temporary, come back later". Google pauses without dropping your pages. Never serve maintenance notices with a 200, and keep genuine downtime short: persistent 5xx eventually costs indexing.
Checking Status Codes in Thirty Seconds
You never have to guess what a URL returns:
- One URL, from a terminal.
curl -Ishows the status line; add-Lto follow and print every hop of a redirect chain:
curl -sI https://example.com/some-page/ # first line: HTTP/2 200
curl -sIL https://example.com/old-page/ # prints every hop in the chain
curl -sI -A "Googlebot" https://example.com/ # what your firewall serves to bots
- One URL, as Google sees it. URL Inspection in Search Console shows the status code from Google's last real crawl, plus the indexing verdict that followed.
- The whole site. Search Console's page indexing report groups every excluded URL by reason: "Not found (404)", "Soft 404", "Page with redirect", "Blocked due to access forbidden (403)", "Server error (5xx)". A crawler like Screaming Frog (free for 500 URLs) gets you the same data on demand, plus every internal link that points at a non-200 URL.
The Mistakes I Keep Finding on Audits
- The custom 404 page that returns 200. Beautifully designed, correctly worded, wrong status code. Every dead URL on the site becomes an indexable page.
- Migration chains. http to https to www to new-slug: four hops before content. Each stacked migration added a layer, and nobody flattened them. Collapse chains to one hop and update internal links to final URLs.
- Permanent moves on 302s. Some platforms and load balancers default to temporary redirects. Google keeps the old URL canonical, the new page inherits nothing, and the migration "mysteriously" underperforms.
- Everything redirects to the homepage. The lazy migration: 3,000 old URLs, one destination. Google calls this out by name as likely soft 404 treatment, and every one of those URLs loses whatever it had earned.
- Firewalls serving Googlebot a 403. Bot protection tuned too aggressively blocks the one bot you wanted. If pages drop from the index while working fine in your browser, test with a Googlebot user agent first.
- Maintenance behind a 200. A week of "back soon" served as success, and Google indexes the apology. Use a 503 with Retry-After, and keep it short.
- Internal links pointing at dead or redirected URLs. The codes are correct; the links are stale. Every internal link into a 404 wastes the click, and every link into a 301 wastes a hop. Crawl your own site and point links at final URLs.
The Status Code Checklist
Run this against your site today
- Every page you care about returns 200 (spot-check with curl -I)
- Permanent moves use 301 or 308, in a single hop
- Redirects point at like-for-like pages, not the homepage
- Deleted content returns 404 or 410, and the error page itself returns the real code
- No "Soft 404" entries in Search Console's page indexing report
- Maintenance windows return 503 with a Retry-After header
- Firewall and bot protection serve Googlebot 200s, not 403 challenges
- Internal links point at final URLs: no links into 404s or redirect hops
- Sitemap contains only 200 URLs
- Robots.txt returns 200 or 404, never a 5xx
Not Sure What Your URLs Are Actually Returning?
Status code problems hide well: the site looks fine in a browser while Googlebot sees 403s, chains and soft 404s. I check response codes, redirects, indexing and the full crawl path in my free audit, personally, and tell you what I'd fix first.
Get My Free Audit