Коды ошибок LLM API у разных провайдеров: справочник по 4xx/5xx, стратегии повторов и граничные случаи
Практический справочник по HTTP-ошибкам API OpenAI, Anthropic, DeepSeek и DashScope. Мы сравнили ошибки аутентификации, варианты rate-limit, отказы фильтров контента, ответы при отсутствии модели и ошибки внутри SSE-потоков — а затем построили дерево решений: когда повторять запрос, когда переключаться на другого провайдера и когда сразу возвращать ошибку.
Каждый LLM API возвращает ошибки по-разному. OpenAI использует четыре варианта 429. Anthropic ввёл 529. DeepSeek выделил отдельный 402. DashScope оборачивает ошибки в конверт code/message, который иногда противоречит HTTP-статусу.
Если вы маршрутизируете запросы между несколькими провайдерами, вам нужна единая ментальная модель. Мы создали этот справочник для собственного routing-слоя и обновляем его при изменении поведения ошибок у провайдеров.
OpenAI-совместимость означает, что провайдер предоставляет endpoint chat-completions, чей контракт запроса и ответа достаточно близок к API OpenAI, чтобы немодифицированный вызов OpenAI SDK работал после замены трёх значений: API key, base URL, название модели. Минимальная поверхность на практике —POST /v1/chat/completions с messages, model и потоковым ответом в форме OpenAI.
TL;DR — сводная таблица кодов ошибок
| HTTP-статус | Тип ошибки | OpenAI | Anthropic | DeepSeek | DashScope | Повтор? | Рекомендуемое действие |
|---|---|---|---|---|---|---|---|
| 400 | Некорректный запрос | invalid_request_error | invalid_request_error | Invalid Format / Invalid Parameters (422) | InvalidParameter | Нет | Исправить тело запроса |
| 401 | Аутентификация | invalid_authentication | authentication_error | Authentication Fails | InvalidApiKey (HTTP 400) | Нет | Проверить API key |
| 402 | Биллинг | — | — | Insufficient Balance | — | Нет | Пополнить баланс |
| 403 | Доступ | country_not_supported | permission_error | — | — | Нет | Проверить доступ/регион |
| 404 | Не найдено | — | not_found_error | — | ModelNotFound | Нет | Исправить model ID |
| 413 | Слишком большой | — | request_too_large | — | — | Нет | Уменьшить входные данные |
| 429 | Rate limit | rate_limit_error + 3 billing-варианта | rate_limit_error | Rate Limit Reached | Throttling / FlowControl | Да (rate); Нет (billing) | Backoff; проверить Retry-After |
| 500 | Ошибка сервера | server_error | api_error | Server Error | InternalError | Да | Повтор с backoff |
| 503 | Перегрузка | overloaded / slow_down | — | Server Overloaded | ServiceUnavailable | Да | Повтор с backoff |
| 529 | Перегрузка | — | overloaded_error | — | — | Да | Повтор с backoff |
Данные получены 31 июля 2026. OpenAI — developers.openai.com/api/docs/guides/error-codes. Anthropic — platform.claude.com/docs/en/api/errors и github.com/anthropics/skills. DeepSeek — api-docs.deepseek.com/quick_start/error_codes. DashScope — alibabacloud.com/help/en/model-studio/error-code.
Ошибки аутентификации: 401 vs 403
Ошибки аутентификации никогда не подлежат повтору, но провайдеры сигнализируют о них по-разному.
OpenAI возвращает 401 для четырёх причин: невалидный key, неправильный формат key, отсутствие членства в организации и несовпадение IP-whitelist. Также используется 403 для неподдерживаемых стран/регионов — это географическое ограничение, а не проблема учётных данных.
Anthropic чётко разделяет 401 (аутентификация — неправильный или отсутствующий key) и 403 (разрешения — key не имеет доступа к конкретной модели или beta-функции). Важная деталь: если вы передадите OAuth bearer token через x-api-key вместо Authorization: Bearer, вы получите 401, а не 403.
DeepSeek возвращает 401 для всех сбоев аутентификации. 403 в документированной поверхности ошибок не используется.
DashScope возвращает 400 с кодом InvalidApiKey для сбоев аутентификации — не 401. Это особенность их конверта ошибок: HTTP-статус 400, но семантический код ошибки внутри тела ответа указывает на проблему аутентификации. Если вы парсите только HTTP-статусы, вы ошибочно классифицируете это как «некорректный запрос».
Практический вывод
Не полагайтесь на HTTP 401 для обнаружения сбоев аутентификации у разных провайдеров. Парсите тело ошибки. InvalidApiKey от DashScope приходит как 400.
Ошибки rate-limit: разновидности 429
Rate-limit — самая сложная категория, потому что провайдеры перегружают 429 для принципиально разных проблем.
OpenAI: четыре типа 429
OpenAI возвращает 429 для четырёх причин, каждая с отдельным error.code:
rate_limit_reached— превышен RPM или TPM. Можно повторить после интервала из заголовкаRetry-After.credit_balance_exhausted— предоплаченные кредиты исчерпаны. Повтор бесполезен; нужно пополнить.organization_spend_limit_exceeded— лимит расходов организации. Повтор бесполезен; нужно поднять лимит.project_spend_limit_exceeded— лимит расходов проекта. Повтор бесполезен; нужно поднять лимит.
Ключевое отличие: только первый тип подлежит повтору. Остальные три требуют действий на уровне аккаунта. Повторные запросы для billing-вариантов 429 с exponential backoff — пустая трата ресурсов.
Anthropic: чистый 429 + уникальный 529
Anthropic использует 429 только для rate limit (RPM, ITPM, OTPM). Они предоставляют заголовки retry-after, x-ratelimit-limit-* и x-ratelimit-remaining-*. SDK автоматически повторяет 429 и 5xx с exponential backoff (по умолчанию 2 повтора).
Уникальное решение Anthropic: 529 overloaded_error для исчерпания ёмкости. Это отличается от 500 api_error (баг сервера). Оба подлежат повтору, но 529 конкретно означает «мы заняты, попробуйте позже» — а не «что-то сломалось».
DeepSeek: 429 для rate-limit, 402 для биллинга
DeepSeek сохраняет простоту: 429 — rate limit, 402 — недостаточный баланс. Никаких billing-вариантов 429. 402 — ясный сигнал: прекратить повторы и пополнить счёт.
DashScope: Throttling vs FlowControl
DashScope возвращает 429 с двумя внутренними кодами: Throttling (превышен QPM/TPM для конкретной модели) и FlowControl (системный flow-контроль при высокой нагрузке). Оба подлежат повтору, но FlowControl может означать более долгое ожидание. DashScope также поддерживает временное повышение лимитов через консоль.
Ошибки фильтрации контента
Отказы фильтра контента приходят как 400 у всех провайдеров, но с разными внутренними кодами:
- OpenAI:
400с упоминаниемcontent_filterв сообщении. В streaming — finish reasoncontent_filterв chunk. - Anthropic:
400 invalid_request_errorпри нарушении политики использования. Отдельного типа ошибки нет. - DeepSeek:
400 Invalid Formatс сообщением о нарушении политики контента. - DashScope:
400с кодомDataInspectionFailed— самый описательный код из четырёх.
Ошибки фильтрации контента никогда не подлежат повтору с тем же входом. Необходимо изменить содержимое запроса.
Ошибки «модель не найдена» и устаревшие модели
Когда вы запрашиваете несуществующую или устаревшую модель:
- OpenAI:
404с сообщением, перечисляющим model ID и предлагающим альтернативы. - Anthropic:
404 not_found_error. Частая причина: опечатка в model ID (например,claude-sonnet-4.6вместоclaude-sonnet-4-6). Алиасы вродеclaude-opus-5работают. - DeepSeek: документированного
404нет — пространство моделей DeepSeek невелико и стабильно. - DashScope:
400с кодомModelNotFoundилиInvalidModel. После даты вывода модели запросы возвращают эту ошибку.
Плавная деградация для устаревших моделей
Если вы маршрутизируете через несколько провайдеров, ошибка «модель не найдена» должна запускать fallback на эквивалентную модель — а не повтор. См. руководство по fallback-маршрутизации.
Ошибки внутри SSE-потоков
Streaming (SSE) создаёт тонкую проблему: HTTP-соединение возвращает 200 при начальном handshake, но ошибки могут возникнуть в середине потока, когда вы уже обрабатываете chunk-и.
- OpenAI: может отправить событие ошибки внутри SSE-потока. Начальный HTTP-статус —
200, поэтому нужно проверять каждый chunk. Поток может просто оборваться без маркера[DONE]при серверных ошибках. - Anthropic: отправляет
content_block_stopилиmessage_stopпри успехе и отдельный тип событияerrorпри неудаче. Типизированный протокол делает обнаружение ошибок чётче. - DeepSeek: следует OpenAI-совместимому SSE-формату. Ошибки в середине потока приходят как error-chunk-и.
- DashScope: при использовании OpenAI-совместимого endpoint следует тому же шаблону SSE-ошибок, что и OpenAI.
Подробнее — в руководстве по cross-provider streaming.
Практический вывод
Никогда не считайте HTTP 200 гарантией успеха всего ответа. Всегда реализуйте обработку ошибок на уровне потока.
Нормализация ошибок в gateway
При маршрутизации запросов между провайдерами разнородные форматы ошибок — реальная проблема: клиентскому коду нужно N обработчиков для N провайдеров. Routing gateway должен нормализовать upstream-ошибки в единый downstream-контракт.
Рекомендуемое сопоставление:
| Downstream-класс | Источник | Повтор | Действие |
|---|---|---|---|
auth_error | 401, 403, DashScope InvalidApiKey | Нет | Исправить учётные данные |
invalid_request | 400 (кроме фильтра контента), 413, 422 | Нет | Исправить запрос |
content_filtered | 400 + флаг политики контента | Нет | Изменить контент |
rate_limited | 429 (только rate-варианты) | Да | Backoff + повтор |
billing_error | 402, 429 (billing-варианты) | Нет | Пополнить / поднять лимит |
model_unavailable | 404, ModelNotFound | Нет | Fallback на другую модель |
provider_error | 500, 503, 529 | Да | Повтор → fallback |
Сохраняйте оригинальный код ошибки и сообщение провайдера в поле метаданных. Разработчикам, отлаживающим инцидент в production, нужно видеть исходный credit_balance_exhausted, а не просто «billing_error».
TheRouter маршрутизирует OpenAI-совместимые запросы через настроенных провайдеров и поддерживает fallback моделей при наличии рабочих путей. Нормализация ошибок — часть routing-контракта: upstream 429 и 5xx запускают fallback-цепочки при настройке.
Дерево решений: повтор vs fallback vs fail
Получена ошибка
├── HTTP-статус 429?
│ ├── error.code — billing/spend/credit?
│ │ └── FAIL — повтор бесполезен; нужно действие на уровне аккаунта
│ └── error.code — rate-limit?
│ ├── Есть заголовок Retry-After?
│ │ └── ЖДАТЬ указанное время, затем ПОВТОРИТЬ у того же провайдера
│ └── Нет Retry-After
│ └── ПОВТОРИТЬ с exponential backoff (макс. 3 попытки)
│ └── Всё ещё ошибка? → FALLBACK на следующего провайдера
├── HTTP-статус 500, 503 или 529?
│ └── ПОВТОРИТЬ с exponential backoff (макс. 3 попытки)
│ └── Всё ещё ошибка? → FALLBACK на следующего провайдера
├── HTTP-статус 400 (фильтр контента)?
│ └── FAIL — контент нужно изменить; fallback не поможет
├── HTTP-статус 400, 401, 403, 404, 413 или 422?
│ └── FAIL — проблема клиента; исправить запрос
└── HTTP-статус 402?
└── FAIL — проблема биллинга; пополнить баланс
Часто задаваемые вопросы
Какие ошибки LLM API безопасно повторять?
HTTP 429 (только rate-limit, не billing-варианты), 500 (ошибка сервера), 503 (перегрузка) и 529 (перегрузка Anthropic) обычно безопасны для повтора с exponential backoff. Все ошибки 400-серии, кроме rate-limit 429, требуют клиентских изменений. См. сравнение rate-limit.
Почему OpenAI возвращает разные типы ошибок 429?
OpenAI использует 429 минимум для четырёх разных причин: RPM/TPM rate limit, исчерпание кредитов, лимит расходов организации и лимит расходов проекта. Проверяйте поле error.code: rate_limit_reached, credit_balance_exhausted, organization_spend_limit_exceeded и project_spend_limit_exceeded. Только rate_limit_reached подлежит повтору.
Что такое код 529 у Anthropic?
Anthropic возвращает HTTP 529 (overloaded_error), когда API временно достиг предела нагрузки. Это отличается от 500 (api_error, означает баг сервера). Оба подлежат повтору с exponential backoff. При постоянных 529 рассмотрите маршрутизацию к менее нагруженной модели — модели класса Haiku обычно имеют больше доступной ёмкости.
Чем подход DeepSeek к недостаточному балансу отличается от OpenAI?
DeepSeek возвращает выделенный HTTP 402 (Insufficient Balance), тогда как OpenAI объединяет это в 429 с кодом credit_balance_exhausted. Подход DeepSeek яснее — 402 никогда не подлежит повтору и всегда означает необходимость пополнения.
Различается ли сигнализация ошибок внутри SSE-потоков?
Да. Все провайдеры могут вернуть HTTP 200 для начального SSE-соединения, но затем отправить ошибку внутри потока. Всегда реализуйте обработку ошибок на уровне потока — не полагайтесь на 200 как на гарантию. См. руководство по streaming.
Как routing gateway нормализовать ошибки?
Сопоставьте upstream-ошибки с единым downstream-контрактом: auth_error, invalid_request, rate_limited, content_filtered, model_unavailable или provider_error. Сохраняйте оригинальный код и сообщение в метаданных. Так клиент пишет один retry/fallback-обработчик. См. сравнение gateway.
Где проверить статус провайдеров при сбоях?
- OpenAI: status.openai.com
- Anthropic: status.anthropic.com
- DeepSeek: status.deepseek.com
- DashScope: страница статуса Alibaba Cloud или консоль Model Studio