# X_SCRAPE_HTTP_FAILED

## Means

the site answered the HTTP leg with a non-2xx status

## Typical cause

**retryable by default** — 429, 5xx and a deploy window are transient far more often than not. A 4xx that `isRetryableStatus` (`@ultimat3/core`) calls permanent is thrown with a per-instance `terminal` override, because the same code is both and only the throw site knows which it saw — **408, 409, 425 and 429 keep their attempts** `As of 2026-08-23`. This row said "below 500 other than 429" until then, and a private copy of the table here called 408 and 425 terminal while the rest of the framework called them retryable; a terminal classification dead-letters the run on the attempt that failed rather than spending its declared `attempts`

## Fix

confirm the endpoint the browser leg calls is the one this request names — `page.network()` lists every URL the page actually fetched

[Scraping](/error-codes#scraping)
