> ## Documentation Index
> Fetch the complete documentation index at: https://firecrawl-claude-eager-dijkstra-21lyl6.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 错误

> 所有 API 错误代码、成因、处理方法，以及是否应重试。

每个 Firecrawl 错误响应都采用相同的 JSON 结构。请在下表中查找 `error` 的值 (或 HTTP 状态码) ，以了解错误原因、处理方法，以及该请求是否可以安全重试。

<Note>本文涵盖了大多数代理和客户端会遇到的错误，但并非完整列表——如果你遇到了此处未列出的错误，请[提交 issue](https://github.com/firecrawl/firecrawl/issues)，以便我们将其补充到文档中。</Note>

<div id="error-response-shape">
  ## 错误响应结构
</div>

所有非 2xx 响应都会返回 JSON，顶层包含 `success: false` 和字符串类型的 `error`。某些端点在可提供更多上下文信息时，还会包含其他字段 (`details`、`code`) 。

```json theme={null}
{
  "success": false,
  "error": "Unauthorized: Invalid token",
  "details": "Optional structured details (only present on some errors)"
}
```

| 字段 | 类型 | 描述 |
| - | - | - |
| `success` | `boolean` | 出错时始终为 `false`。 |
| `error` | `string` | 便于人工阅读的错误消息。可据此查找下方对应的行。 |
| `details` | `any` | 可选。适用时，包含按字段组织的结构化验证错误信息。 |

<div id="errors">
  ## 错误
</div>

| HTTP | `error` (典型消息) | 原因 | 处理方法 | 可重试 |
| - | - | - | - | - |
| 400 | `Bad Request` / 验证消息 | 请求体未通过 schema 验证 (字段缺失或无效) 。 | 根据 endpoint 参考文档修正请求 payload。检查 `details` 中的字段。 | 否 |
| 400 | `Invalid URL` | `url` 字段缺失、格式错误，或使用了不受支持的协议。 | 传入绝对 `http(s)://` URL。 | 否 |
| 401 | `Unauthorized: Invalid token` | API 密钥缺失、格式错误或已被撤销。 | 发送 `Authorization: Bearer fc-...`，并使用 [Dashboard](https://www.firecrawl.dev/app/api-keys) 中的有效密钥。 | 否 |
| 402 | `Payment Required: Insufficient credits` | 套餐额度已用尽，或尚未配置计费。 | 充值额度、启用 auto-recharge，或升级你的套餐。 | 否 |
| 403 | `Forbidden` | 该密钥没有访问此 endpoint 或功能的权限。 | 使用具备所需 scope 的密钥，或升级包含该功能的套餐。 | 否 |
| 404 | `Not Found` | 任务 ID、资源或 endpoint 路径不存在。 | 核实资源 ID 和 endpoint URL。 | 否 |
| 408 | `Request Timeout` | 页面加载时间超过了请求 `timeout`。 | 增加 `timeout`、简化 actions，或使用 `fastMode`。 | 是，需退避重试 |
| 409 | `Conflict` | 资源当前所处状态阻止了该操作 (例如已被删除) 。 | 重试前重新获取状态并完成协调。 | 否 |
| 413 | `Payload Too Large` | 请求体超过允许的最大大小。 | 缩减 payload (例如缩短 schema、减少每个 batch 中的 URL 数量) 。 | 否 |
| 422 | `Unprocessable Entity` / 提取 schema 错误 | schema 不是有效的 JSON Schema，或模型无法生成符合要求的结果。 | 验证 schema；放宽必填字段；尝试其他 `model`。 | 有时 |
| 429 | `Rate limit exceeded` | 请求次数超过了你的套餐每分钟限额。 | 退避，并在 `Retry-After` 指定的秒数后重试。请参见 [限流](/zh/rate-limits)。 | 是，需退避重试 |
| 429 | `Concurrency limit reached` | 已达到你的套餐并发浏览器数上限。 | 等待进行中的任务完成、降低并发，或升级你的套餐。 | 是，需退避重试 |
| 500 | `Internal Server Error` | 服务端发生了未处理的故障。 | 使用指数退避重试。如果问题持续存在，请附上请求 ID 联系支持团队。 | 是，需退避重试 |
| 502 | `Bad Gateway` | 上游代理或工作进程返回了无效响应。 | 退避后重试。 | 是，需退避重试 |
| 503 | `Service Unavailable` | 服务暂时无法处理该请求。 | 退避后重试。 | 是，需退避重试 |
| 504 | `Gateway Timeout` | 请求超过了网关超时时间 (通常见于长时间爬取) 。 | 改用异步爬取/batch 端点，并改为轮询状态。 | 是，需退避重试 |

对于 429 响应，Firecrawl 会在可用时包含 `Retry-After` 响应头 (单位为秒) ——重试前至少等待这么久。

<div id="retry-guidance">
  ## 重试指南
</div>

以 **可重试** 列为准；不要仅凭 HTTP 状态码自行判断。以下模式使用带抖动的指数退避，并在遇到 429 时遵循 `Retry-After`。

<CodeGroup>
  ```python Python theme={null}
  import time
  import random
  import requests

  RETRYABLE_STATUSES = {408, 429, 500, 502, 503, 504}

  def request_with_retry(method, url, headers=None, json=None, max_attempts=5):
      for attempt in range(max_attempts):
          resp = requests.request(method, url, headers=headers, json=json)
          if resp.status_code < 400 or resp.status_code not in RETRYABLE_STATUSES:
              return resp
          # 存在 Retry-After 时优先遵循，否则使用带抖动的指数退避。
          retry_after = resp.headers.get("Retry-After")
          delay = float(retry_after) if retry_after else min(2 ** attempt, 30) + random.random()
          time.sleep(delay)
      return resp
  ```

  ```js Node theme={null}
  const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);

  async function requestWithRetry(url, init = {}, maxAttempts = 5) {
    for (let attempt = 0; attempt < maxAttempts; attempt++) {
      const resp = await fetch(url, init);
      if (resp.ok || !RETRYABLE_STATUSES.has(resp.status)) return resp;
      // 存在 Retry-After 时优先遵循，否则使用带抖动的指数退避。
      const retryAfter = resp.headers.get('Retry-After');
      const delayMs = retryAfter
        ? Number(retryAfter) * 1000
        : Math.min(2 ** attempt, 30) * 1000 + Math.random() * 1000;
      await new Promise((r) => setTimeout(r, delayMs));
    }
  }
  ```

  ```bash cURL theme={null}
  # 针对可重试状态码使用指数退避的简单 shell 循环。
  attempt=0
  max=5
  until response=$(curl -sS -w "\n%{http_code}" -X POST "https://api.firecrawl.dev/v2/scrape" \
      -H "Authorization: Bearer $FIRECRAWL_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"url":"https://example.com"}'); do
    status=$(printf '%s' "$response" | tail -n1)
    case "$status" in
      408|429|500|502|503|504)
        attempt=$((attempt+1))
        [ "$attempt" -ge "$max" ] && break
        sleep $((2 ** attempt))
        ;;
      *) break ;;
    esac
  done
  echo "$response"
  ```
</CodeGroup>

<div id="429-responses">
  ## 429 响应
</div>

429 响应是最常见的可重试错误。各套餐的限流和并发限制详见[限流](/zh/rate-limits)。如果存在 `Retry-After` 标头，请务必遵循其指定的等待时间，而不要立即重试。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.