Ошибка 503 — провайдер модели недоступен

503 говорит, что проблема не у вас. Разбираем, как её пережить без потери данных и почему при стриминге ошибка приходит с кодом 200.

2 мин · · Обновлено · ошибки · надёжность · стриминг

Код 503 означает, что сервис временно не может обработать запрос. Применительно к API моделей это чаще всего значит, что недоступен не сам шлюз, а провайдер модели за ним.

Отдельный случай — 503 с кодом model_disabled: модель выключена в Zukko, и повторы не помогут. Замените её на включённую — актуальный список даёт GET https://api.zukko.pro/v1/models, а статус моделей — публичный GET https://api.zukko.pro/api/status.

Чем отличается от соседей

503 — временная недоступность. Запрос корректный, повторять имеет смысл.

500 — внутренняя ошибка. Тоже не ваша вина, но повтор помогает реже: если запрос воспроизводимо ломает обработку, он сломает её и на второй раз.

429 — превышена частота на стороне провайдера модели; повторять с задержкой обязательно. Своего ограничения частоты у шлюза Zukko нет: 429 от самого Zukko означает лимит расходов ключа (key_daily_limit_reached со сбросом в 00:00 UTC или key_monthly_limit_reached), и повтор тут не поможет.

502 — сбой связи с вышестоящим сервисом.

Практическая разница в том, сколько ждать. Для 429 от провайдера ориентируйтесь на заголовок Retry-After. Для 503 разумны интервалы от нескольких секунд до минуты: если провайдер лёг, секундные повторы только добавят ему нагрузки.

Важная особенность: 503 при стриминге приходит с кодом 200

Это ловушка, на которой ломается обработка ошибок в самописных клиентах.

При потоковом запросе соединение открывается сразу, заголовки уходят с кодом 200, и только потом внутри потока приходит событие с ошибкой:

data: {"error":{"message":"Провайдер модели временно недоступен","type":"service_unavailable"}} data: [DONE]

Код ответа при этом 200, и клиент, который проверяет только его, посчитает запрос успешным и вернёт пустой результат.

Что делать: разбирать содержимое потока, а не только статус. Если в событии есть поле error, это ошибка независимо от кода ответа. И не тарифицируйте у себя такие запросы, если ведёте свой учёт, — токенов в них нет.

Как пережить недоступность

Повторяйте с растущей задержкой. Три-четыре попытки с интервалами 5, 15, 45 секунд покрывают большинство коротких сбоев.

Ограничьте число попыток. Бесконечный цикл при длительной аварии превращается в зависший процесс.

Сохраняйте состояние до вызова. В агентных сценариях самое дорогое при сбое — потерять контекст работы. Если состояние сохранено, после восстановления вы продолжите, а не начнёте заново.

Предусмотрите запасную модель. Недоступность обычно затрагивает одну линейку, а не все сразу. Переключение на другую модель того же класса часто дешевле ожидания.

Когда это техработы

Если ответ приходит мгновенно и стабильно, с понятным текстом про технические работы и заголовком Retry-After, — это плановая остановка, а не авария. Повторы тут бесполезны до окончания работ, зато и деньги за такие запросы не списываются.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.