# Troubleshooting

What each error returned by `Fetch` means, where it comes from, and whether a headed retry will happen.

## Status errors

These are `*browser.Error` values; read the code with `errors.As` and `Error.Status`.

| Error | Raised when | Headed retry |
|---|---|---|
| `http 403` | The post-redirect URL has a `403` path segment or query value; the first snapshot's title matches a challenge page (`just a moment`, `attention required`, `checking your browser`, `access denied`, `請稍候`); or no article was extracted and the response status is 403 | Yes, when a GUI is available |
| `http 429` / `http 503` | No article was extracted and the response status is 429 or 503 | Yes, when a GUI is available |
| `http 404` | The post-redirect URL has a `404` path segment or query value, or no article was extracted and the status is 404 | No |
| `http 204` | Extraction succeeded but the Markdown is empty after deduplication | No |
| other `http 4xx/5xx` | No article was extracted and the response status is 400 or higher | No |

A `403` / `429` / `503` that arrives as `Result.Status` on a successful result also counts as blocked and triggers the same retry. See [Fetch Routing](/core-concepts-routing).

## Plain errors

| Message | Cause |
|---|---|
| `invalid url: ...` | The URL has no scheme, or the hostname contains no `.` |
| `readability: no article extracted from N snapshots` | No snapshot parsed into an article and the status was below 400 |
| `acquireSem: context deadline exceeded` | The concurrency cap was full until `timeout` expired; see [Browser Cache](/core-concepts-browser-cache) |
| `launcher.Launch: ...` | Chrome failed to start, usually a missing binary or a sandbox restriction |
| `security find-generic-password: ...` | macOS keychain locked or access denied; only reached with `SameSession` |
| `secret-tool application=chromium: ...` | Neither `chrome` nor `chromium` has a secret in the Linux keyring; only with `SameSession` |
| `sqlite3: ...` | `sqlite3` missing or the cookie database unreadable; only with `SameSession` |
| `inject cookies (0/N): ...` | Every cookie failed to inject, even one by one |

A missing Chrome profile wraps `browser.ErrProfileNotFound` internally, but `Fetch` does not return it: the call continues on a regular browser without cookies. The other `SameSession` errors above are returned as-is and do not fall back.

## Headless servers

A Linux host with neither `DISPLAY` nor `WAYLAND_DISPLAY` never launches a headed browser, so blocked responses come back as errors instead of being retried. See [Environment](/configuration-environment).
