All articles
Bot traffic / July 24, 2026

How to spot server throttling and inconsistent status codes blocking your crawlers

16 min read
On this page

Server throttling and inconsistent status codes are among the most damaging problems in technical SEO precisely because they are invisible from a browser. Your homepage loads fine, your team sees 200s all day, and yet Googlebot, GPTBot, and ClaudeBot are quietly collecting 403s, 429s, and 503s on the same URLs.

The traffic decline shows up weeks later as pages slipping out of the index or vanishing from AI answers, long after the root cause has scrolled off the top of your logs. The gap between “works in my browser” and “works for the crawler” is where rankings go to die.

This is a diagnosable, fixable class of problem. The key is to look at your traffic the way a crawler experiences it, not the way a person does.

What server throttling and inconsistent status codes actually are

Server throttling is the deliberate or accidental limiting of how many requests a client can make in a given window, usually enforced by returning a 429 or 503 once a threshold is crossed. Inconsistent status codes are the related symptom: the same URL returning different HTTP responses depending on who is asking, when they ask, or how many times they have asked recently.

Both problems share a root trait. The response a client receives is a function of more than the URL. It depends on the requester’s user agent, IP address and reputation, request rate, geography, and whether an edge security layer decided to issue a challenge. A person on a residential connection sails through. A crawler hitting a hundred URLs a minute from a datacenter IP range trips a rule the person never touches.

Throttling is not inherently wrong. Rate limiting protects origin servers from being overwhelmed, and returning a 429 with a Retry-After header is the correct way to tell an aggressive client to slow down. The damage comes from two failure modes: limits set so low that legitimate crawlers cannot make progress, and blanket security rules that treat every non-browser client as hostile. You may have never intended to block Googlebot, but a web application firewall rule written to stop scrapers will happily return 403 to any client that does not send browser-like headers, and honest crawlers do not. The next sections show how to see this happening and trace it to its source.

Which status codes crawlers care about and how they react

Crawlers interpret status codes as instructions, and the difference between two adjacent codes can be the difference between a temporary slowdown and permanent removal from the index. Google’s documented behavior draws a hard line between codes that mean “come back later” and codes that mean “this content is gone.”

The critical detail most site owners miss: a 403 and a 429 look similar in a log file but are treated in completely opposite ways. Google treats 403 and 401 the same as a 404, a signal that the content does not exist, and previously indexed pages get removed. A 429 is read as an overload signal and only slows crawling. Using 403 to fend off aggressive bots therefore risks deindexing the very pages you want ranked.

Status codeWhat it means to a crawlerHow Googlebot / AI crawlers reactCorrect use / fix
200 OKContent served successfullyNormal crawl and indexing; a 200 that returns an error or empty page becomes a “soft 404” and is droppedReturn 200 only for real content
403 ForbiddenAccess denied, treated as “content does not exist”Google treats it like a 404 and removes the URL from the index; a hard stop, not a slowdownNever use to throttle; reserve for genuinely private content
429 Too Many RequestsServer overload, slow downGooglebot and Bingbot reduce crawl rate; persisting beyond ~2 days drops URLs from the indexPair with a Retry-After header; raise the limit for verified crawlers
503 Service UnavailableTemporary outage, retry laterCrawl rate reduced; safe for 1-2 days, but multi-day 503s cause pages to be droppedUse for planned maintenance only, with Retry-After
500 / 502 / 5xxServer errorCrawl rate cut proportionally to affected URLs; sustained errors shrink crawl budget and deindexFix the origin; do not let errors persist for days

AI crawlers follow broadly similar logic but with less tolerance and less consistency. GPTBot, ClaudeBot, and PerplexityBot are built to back off on a 429 with Retry-After, and well-behaved clients apply exponential backoff, doubling the wait after each failure. But their crawl budgets are tighter and their revisit schedules are opaque, so a stretch of 429s or 503s can mean a page simply never makes it into the model’s training set or the retrieval index behind a live answer.

Two operational facts anchor everything that follows. First, 403 causes removal while 429 causes slowdown, so the code you choose has strategic consequences, the same way choosing the right redirect code does. Second, duration is decisive: a few hours of errors is survivable, but errors that persist for roughly two days to a week push Google to treat affected URLs like 404s and drop them. The goal of detection is to catch these patterns inside that window, not after.

How to detect intermittent crawler blocking

You detect intermittent crawler blocking by segmenting your status codes by client, because the problem is invisible in any aggregate that mixes human and bot traffic. A 99.4% success rate across all requests can hide a 40% failure rate for Googlebot, since humans vastly outnumber crawlers and drown out the signal.

Start with the data sources that show what crawlers actually received, not what a browser gets on demand.

  • Server-side access logs. The ground truth. Every request, its user agent, source IP, timestamp, and the exact status code returned. This is the only place that captures what the crawler saw, because a browser retest happens later and under different conditions.
  • Google Search Console. The Crawl Stats report (Settings, then Crawl stats) breaks Googlebot fetches down by response code and flags spikes in 403, 429, and 5xx. The Pages report surfaces “Blocked due to access forbidden (403)” and “Server error (5xx)” as indexing reasons.
  • Edge and CDN analytics. If a WAF or CDN sits in front of your origin, its logs show challenges and blocks that never reach your application logs at all, which is exactly where challenge-based blocking hides.
  • Dedicated bot analytics. A platform like Lume captures every request server-side at the edge and breaks traffic down by status class, so you can see the non-human half of your traffic on its own terms instead of buried in a blended total.

Once you have the data, look for these specific patterns.

  1. Status codes that vary by user agent for the same URL. If /pricing returns 200 to Chrome and 403 to Googlebot, that is a user-agent or bot rule, not a broken page. This is the single most diagnostic signal, and it is why Lume includes an inconsistent-status detector that flags exactly this: the same URL returning different status codes to different agents.
  2. Clusters of 429 or 503 that track request rate. Plot bot status codes against requests per minute. If failures begin above a threshold, such as 200 requests a minute during a traffic spike, you have found your rate limit.
  3. An “agents-blocked” signal on important crawlers. Watch specifically for verified Googlebot, GPTBot, or ClaudeBot receiving 403, 429, or 503. Lume surfaces this as an explicit agents-blocked signal, so a throttled crawler does not stay buried in the noise.
  4. Bursts that correlate with deploys or rule changes. A block that starts the hour a WAF rule shipped is a strong causal lead.

To reproduce a suspected block on demand, request the URL while spoofing the crawler’s user agent and compare it to a normal browser request:

curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" -I https://example.com/pricing
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" -I https://example.com/pricing

If the first returns 403 and the second 200, the server is discriminating by user agent. One caveat: a sophisticated WAF also checks IP reputation and JavaScript execution, so a curl test from your office IP may pass even when the real Googlebot from a datacenter range is blocked. Absence of a block in a curl test is not proof of innocence. With reliable detection in place, the next task is tracing each pattern to its root cause.

Root causes: why the same URL returns 200 to a browser but 403, 429, or 503 to a crawler

The same URL returns different codes to different clients because the server’s response depends on request attributes that differ between a human and a crawler. Understanding which attribute triggered the block tells you exactly which system to fix.

There are five recurring root causes, roughly in order of how often they bite.

  • User-agent rules. A WAF or application rule blocks or challenges clients whose user agent is not a known browser, or matches a “bad bot” list too broadly. Honest crawlers announce themselves as GPTBot or Googlebot, which is precisely what a naive block rule catches. The browser, sending a normal Chrome user agent, is waved through.
  • IP reputation and datacenter ranges. Crawlers operate from cloud and datacenter IP ranges that carry lower trust scores than residential IPs. A rule that challenges or blocks low-reputation IPs hits crawlers and spares humans on home broadband.
  • Rate limiting and throttling. A per-IP or per-user-agent limit returns 429 or 503 once a crawler exceeds it. A person clicking through a handful of pages never approaches the threshold; a crawler fetching hundreds of URLs a minute crosses it in seconds. During traffic spikes, an origin under load may start shedding crawler requests first.
  • JavaScript challenges. Managed challenges present a JavaScript or interactive test instead of an outright block. A real browser solves it silently, but a crawler that cannot execute the challenge receives what is functionally a block, often a 403 with a cf-mitigated: challenge header. For a non-rendering crawler, a challenge and a block are the same event.
  • Geographic and edge rules. Rules that restrict or challenge traffic by region catch crawlers fetching from a data center in a blocked geography while local human visitors pass.

A concrete scenario ties these together. A news site enables an aggressive bot-mitigation rule ahead of a product launch. During the resulting traffic spike, the WAF starts returning 429 to any client exceeding 200 requests a minute. Googlebot, crawling fresh articles at exactly that moment, hits the ceiling and backs off. The new articles are never fetched, never indexed, and the site quietly loses the news cycle it built the content for, while every human visitor saw a fast, healthy site the entire time.

The spoofing complication makes root-cause analysis harder. Research through 2025 found that around 5.7% of traffic claiming to be from well-known AI crawlers is fake, with some spoof rates far higher. If you loosen a rule to let “Googlebot” through by user agent alone, you also let every impersonator through. This is why verification matters: you need to know whether a throttled request came from the real crawler or a spoofed one before you decide how to respond. Because Lume verifies agents cryptographically rather than trusting the user-agent string, it can tell a genuinely throttled Googlebot from a spoofed one, which changes whether the right fix is to raise a limit or tighten a rule. With causes identified, remediation becomes a matter of matching the fix to the mechanism.

How to fix throttling and inconsistent status codes

You fix crawler blocking by allowing verified legitimate crawlers ahead of your security rules and by choosing status codes that match your actual intent. Most of the damage comes from good rules applied in the wrong order or the wrong code chosen for the situation.

Work through these fixes in priority order.

  1. Allowlist verified crawlers first in the rule chain. Put an explicit allow for verified search and AI crawlers before any block or challenge rule. If the allow does not come first, your later block and challenge rules catch Googlebot too. Crucially, allow by verification, not by user-agent string alone, or you open the door to spoofers.
  2. Verify crawler identity properly. For Googlebot and other IP-publishing crawlers, use reverse DNS plus forward DNS: run a reverse lookup on the source IP, confirm the hostname belongs to the crawler, then a forward lookup to confirm it resolves back to the same IP. For automation, match the source IP against the crawler’s published IP range file. Never trust the user-agent header by itself.
  3. Replace 403 throttling with 429. If you are using 403 to fend off aggressive bots, switch to 429. A 403 deindexes; a 429 only slows crawling. Always attach a Retry-After header so the crawler knows exactly how long to wait.
  4. Raise or exempt rate limits for verified crawlers. Set crawler limits high enough for legitimate indexing to complete. Different AI crawlers self-pace differently, so a single tight global limit starves the ones that crawl in bursts. Exempt verified crawlers from the general per-IP limit entirely where you can.
  5. Reserve 503 for genuine, short maintenance. Use 503 with Retry-After only for planned downtime, and keep it under one to two days. Beyond that, Google begins dropping the URLs.
  6. Convert blocking challenges to non-blocking checks for good bots. A JavaScript challenge is a block for a non-rendering crawler. Route verified crawlers around managed challenges rather than serving them a test they cannot pass.
  7. Provision for traffic spikes. Since throttling often triggers under load, make sure origin capacity and rate-limit ceilings account for peak crawler-plus-human traffic, so the crawler is not the first request shed.

After any change, confirm the fix from the crawler’s perspective, not just the browser’s. Re-run the user-agent curl comparison, watch Search Console Crawl Stats for the 403 or 429 rate to fall, and confirm in your bot analytics that verified crawlers are back to receiving 200s. A fix you cannot see in crawler-segmented data is a fix you have not verified. Once resolved, the remaining job is making sure it never silently recurs.

How to monitor so it does not silently return

You monitor for crawler blocking by continuously watching crawler-segmented status codes and alerting on any rise in 403, 429, or 5xx to verified important crawlers. Because this problem is invisible to human-focused monitoring, it will recur the moment a new WAF rule or deploy reintroduces it unless something is watching the bot slice specifically.

Build monitoring around a few durable practices.

  • Track status class by verified agent, continuously. Aggregate uptime is not enough. You need the failure rate for Googlebot, GPTBot, and ClaudeBot on their own, verified so spoofed traffic does not distort the numbers. Lume’s Status Codes dashboard is built for exactly this cut: traffic by status class, an inconsistent-status detector, and an agents-blocked signal that fires when important verified crawlers start getting 403, 429, or 503.
  • Alert on the inconsistency, not just the outage. The dangerous pattern is a single URL returning 200 to humans and 403 to crawlers, which never trips an uptime monitor. Alert when the same URL diverges by agent.
  • Gate deploys and rule changes. Treat WAF and CDN rule changes as risky. After any security or infrastructure change, check crawler status codes before considering it done, since these changes are the most common cause of a fresh block.
  • Watch Search Console as a lagging confirmation. Crawl Stats and the Pages report confirm indexing impact, but they lag by days. Use them to validate that a fix worked, not as your first line of detection.

Effective monitoring closes the loop that makes this problem so costly: the long, silent gap between the block starting and the traffic loss becoming visible. Catch the pattern in crawler-segmented data within hours, and it is a minor config fix. Catch it after deindexing, and it is a recovery project.

Frequently asked questions

Why does my site return 200 in the browser but 403 to Googlebot?

Because the server’s response depends on more than the URL. A browser sends a normal user agent from a trusted residential IP and, if challenged, silently executes JavaScript. Googlebot sends a bot user agent from a datacenter IP range and cannot solve interactive challenges. Any WAF, CDN, or application rule keyed on user agent, IP reputation, or JavaScript execution can therefore serve 200 to the human and 403 to the crawler for the identical URL.

Does returning 429 to crawlers hurt my SEO?

A short burst of 429s does not hurt and is the correct way to ask a crawler to slow down, especially with a Retry-After header. The harm comes from persistence. If important pages return 429 for more than roughly two days, Google starts dropping them from the index. Use 429 to smooth out load, not as a permanent wall, and exempt verified crawlers from tight limits so indexing can complete.

How long can my server return 503 before pages get deindexed?

Treat one to two days as the safe ceiling for 503 with a Retry-After header. A few hours of downtime generally has no lasting effect on indexing. Beyond a couple of days, Google begins treating the URLs like 404s and removing them, and by about a week the deindexing risk is serious. For anything longer than planned maintenance, fix the underlying availability rather than serving sustained 503s.

How do I tell a real Googlebot from a spoofed one?

Do not trust the user-agent string, since roughly 5.7% of traffic claiming to be a known AI crawler is fake. Verify by reverse DNS plus forward DNS: run a reverse lookup on the source IP, confirm the hostname belongs to the crawler’s domain, then a forward lookup to confirm it resolves back to the same IP. Alternatively, match the source IP against the crawler’s published IP range file. Cryptographic verification, which Lume performs on every request, removes the guesswork entirely.

Do AI crawlers like GPTBot and ClaudeBot react to throttling the same way Googlebot does?

Broadly yes, but with less tolerance and less transparency. GPTBot, ClaudeBot, and PerplexityBot are designed to back off on a 429 with Retry-After and apply exponential backoff. Their crawl budgets are tighter and their revisit schedules are opaque, so sustained throttling can mean your content never enters the training set or the retrieval index behind a live answer, with no Search Console equivalent to warn you. Monitoring their status codes directly is the only reliable signal.

More posts to read

See the non-human half of your traffic.

Lume shows you every crawler, scraper and AI agent on your site, and verifies which ones are real. Set up in minutes.

Start for free →