Код и данные · HTTPКоды состояния HTTP
Что значит код ответа, кто виноват — клиент или сервер — и что с этим делать. Поиск по номеру, названию и смыслу; шестьдесят четыре кода с практикой, а не только с определением.
Справочник кодов
поиск по номеру, названию и смыслу — «404», «not found», «слишком много запросов»Сервер принял заголовки и готов принять тело запроса. Видно только в клиентах, которые отправляют `Expect: 100-continue`.
Клиент попросил сменить протокол, и сервер согласился. Так начинается WebSocket-соединение.
Запрос принят, обработка идёт долго. Ответ из WebDAV, чтобы клиент не считал соединение зависшим.
Предварительный ответ со ссылками на ресурсы, которые стоит начать загружать до готовности основного ответа.
Запрос выполнен, в ответе есть тело. Самый обычный ответ, который видно на каждой открытой странице.
Ресурс создан. В `Location` — адрес созданного: по нему к нему и обращаются дальше.
Locationадрес созданного ресурсаЗапрос принят, но ещё не выполнен: обработка идёт в фоне. Результат придётся спрашивать отдельно.
Ответ успешный, но изменён посредником — прокси или преобразователем, а не исходным сервером.
Успех без тела ответа. Обычный ответ на удаление или на сохранение, когда возвращать нечего.
Успех, и клиенту предлагается очистить форму, из которой пришёл запрос.
Отдана запрошенная часть файла. Так работают докачка и перемотка видео.
Content-Rangeкакой кусок отданУ ресурса есть несколько представлений, и сервер предлагает выбрать. На практике встречается редко.
Ресурс навсегда переехал по новому адресу из `Location`. Для поиска это перенос веса страницы на новый адрес.
- ·Сменился адрес страницы или домен
- ·Настроен редирект с www на апекс или на https
- →Обновить ссылки на новый адрес — цепочка редиректов замедляет загрузку
- →Убедиться, что переезд действительно постоянный: отменить 301 у кэшировавших клиентов трудно
Locationновый адресВременный редирект: ресурс сейчас доступен по другому адресу, но постоянным этот адрес не считается.
- ·Временная страница: техработы, A/B-тест, авторизация
- →Не кэшировать как постоянный и не переносить ссылки
- →Для постоянного переезда взять 301, иначе поиск продолжит показывать старый адрес
Locationвременный адресПосле обработки запроса результат нужно забрать по другому адресу методом GET. Классический ответ после отправки формы.
Ресурс не менялся с прошлого запроса — клиент берёт его из своего кэша. Тела в ответе нет.
- →Проверить `ETag` и `If-None-Match`, если ответ пришёл неожиданно
ETagметка версии ресурсаТо же, что 302, но метод запроса обязан сохраниться: POST останется POST, а не превратится в GET.
То же, что 301, но с сохранением метода запроса. Правильный выбор для переезда API.
- ·Переезд API или адреса, по которому шлют POST
- →Брать 308 вместо 301 там, где важен метод: старые клиенты на 301 превращают POST в GET
- →Проверить, что клиент действительно повторяет запрос тем же методом
Locationновый адресСервер не понял запрос: сломан синтаксис, не хватает параметров или тело не того формата.
- ·Неверный JSON или другой формат тела
- ·Нет обязательного параметра или он не того типа
- ·Слишком длинный или неправильно закодированный адрес
- →Сверить тело и параметры с документацией API
- →Проверить кодирование значений в адресе
Сервер не знает, кто вы: нужна аутентификация. Несмотря на название, это про «кто ты», а не про права.
- ·Токен не передан, истёк или отозван
- ·Неверный логин или пароль
- →Обновить токен и повторить запрос
- →Проверить заголовок `Authorization` — часто теряется у прокси
WWW-Authenticateкакой способ входа ожидаетсяСервер вас узнал, но выполнять действие не даёт. Это про права, а не про вход: перелогин не поможет.
- ·У роли нет прав на действие или на объект
- ·Доступ закрыт по адресу, стране или правилам файрвола
- →Проверять права, а не токен: 401 и 403 лечатся по-разному
- →Убедиться, что объект принадлежит текущему пользователю
Ресурса по указанному адресу нет. Самый узнаваемый код: страница удалена, адрес набран с опечаткой или ссылка устарела.
- ·Опечатка в адресе или устаревшая ссылка
- ·Страница удалена или переименована без редиректа
- ·Ошибка в маршрутизации приложения
- →Проверить адрес по символам: лишний слэш и регистр имеют значение
- →Для удалённого навсегда ресурса отвечать 410 — это честнее и понятнее поисковику
Адрес существует, но не отвечает на этот метод: например, POST там, где ждут только GET.
- →Посмотреть заголовок `Allow` в ответе и взять метод оттуда
Allowсписок разрешённых методовСервер не может отдать ответ в формате, который клиент готов принять по `Accept`.
То же, что 401, но аутентификации требует прокси между клиентом и сервером.
Клиент слишком долго отправлял запрос, и сервер закрыл соединение.
Запрос противоречит текущему состоянию: дубль записи, устаревшая версия при одновременном редактировании.
- ·Запись с таким уникальным полем уже есть
- ·Кто-то изменил объект между чтением и записью
- →Перечитать текущее состояние и повторить с ним
Ресурс был и удалён окончательно. В отличие от 404 это утверждение: возвращаться нечему.
Сервер отказывается принимать запрос без указанной длины тела.
Не сработало условие из заголовков вроде `If-Match` — обычно защита от перезаписи чужих изменений.
Запрос больше, чем сервер готов принять. Чаще всего — загрузка файла сверх лимита.
Адрес превысил допустимую длину: обычно форма ушла методом GET вместо POST.
Тело пришло в формате, который сервер не принимает: например, `text/plain` вместо `application/json`.
Запрошен кусок файла за его границами — например, докачка после того, как файл изменился.
Сервер не может выполнить условие из заголовка `Expect`.
Шуточный код из первоапрельского RFC 2324 про кофейник: чайник кофе не варит. В реальных API почти не встречается.
Запрос пришёл на сервер, который не может ответить за этот домен.
Синтаксис верный, а значения — нет: почта без собаки, отрицательное количество, дата в прошлом.
- ·Значение не проходит правила валидации API
- →Смотреть тело ответа: в нём обычно перечислены поля с ошибками
- →Отличать от 400 — там сломан сам запрос, здесь только данные
Ресурс заблокирован от изменений — ответ из WebDAV.
Действие не выполнено, потому что не выполнилось предыдущее, от которого оно зависит.
Сервер отказывается обрабатывать запрос, отправленный слишком рано при возобновлении TLS-соединения.
Сервер требует перейти на другой протокол — обычно на HTTPS или на более новую версию HTTP.
Сервер требует условный запрос, чтобы два клиента не перезаписали изменения друг друга.
Превышен лимит частоты. Обычный ответ API при слишком частых обращениях с одного адреса или ключа.
- →Смотреть `Retry-After` и ждать указанное время, а не повторять сразу
- →Добавить паузы между запросами и повтор с увеличением задержки
Retry-Afterчерез сколько можно повторитьЗаголовки запроса превысили лимит сервера — часто из-за разросшихся cookie.
Доступ закрыт по требованию закона: блокировка, судебное решение, требование правообладателя.
- ·Блокировка по требованию регулятора или суда
- ·Требование правообладателя об удалении контента
- →Как посетителю — искать первоисточник: содержимое закрыто не техникой, а решением
- →Как владельцу сайта — отвечать именно 451, а не 403 или 404: код существует затем, чтобы блокировка была видна
Сервер упал на обработке корректного запроса. На стороне клиента не чинится — искать нужно в логах сервера.
- ·Необработанное исключение в коде
- ·Ошибка в конфигурации или недоступная база данных
- →Смотреть логи сервера: тело ответа обычно ничего не объясняет
- →Если это чужой сайт — повторить позже, на клиенте сделать нечего
Сервер не умеет обрабатывать такой метод вовсе — в отличие от 405, где метод не разрешён для конкретного адреса.
Прокси или балансировщик получил от вышестоящего сервера неверный ответ — или не получил никакого.
- ·Приложение за прокси упало или не запущено
- ·Неверный адрес или порт апстрима в конфигурации
- →Проверить, отвечает ли приложение напрямую, минуя прокси
- →Смотреть логи прокси: там видно, к кому он ходил
Сервер временно не может обслужить запрос: перегрузка или плановые работы. Состояние по определению временное.
- ·Плановые работы или перезапуск
- ·Перегрузка: запросов больше, чем сервер тянет
- →Повторить позже, ориентируясь на `Retry-After`
Retry-Afterкогда пробовать сноваПрокси не дождался ответа от вышестоящего сервера за отведённое время.
- ·Бэкенд отвечает дольше таймаута прокси
- ·Тяжёлый запрос: отчёт, экспорт, долгая выборка
- →Измерить время ответа бэкенда и сравнить с таймаутом прокси
Сервер не поддерживает версию протокола из запроса.
Ошибка в настройке согласования содержимого: варианты ссылаются друг на друга по кругу.
На сервере не хватает места, чтобы выполнить запрос — ответ из WebDAV.
Сервер прервал обработку: запрос ведёт к бесконечному циклу.
Сервер требует дополнительных расширений запроса, чтобы его выполнить.
Требуется вход в сеть: типичный ответ портала публичного Wi-Fi.
Код nginx, а не стандарта: клиент отключился раньше, чем сервер успел ответить. Часто значит «человек закрыл вкладку».
Код Cloudflare: сервер вернул ответ, который прокси не смог разобрать.
Код Cloudflare: соединение с исходным сервером отклонено.
Код Cloudflare: не удалось установить соединение с исходным сервером за отведённое время.
Код Cloudflare: исходный сервер недоступен — обычно проблема с DNS или маршрутизацией.
Код Cloudflare: соединение установлено, но ответа не дождались.
Код Cloudflare: рукопожатие TLS с исходным сервером не состоялось.
Частые пары: что с чем путают
301 · 302 · 308
РедиректыНавсегда. Передаёт вес страницы — ссылки стоит обновить.
Временно. Вес не передаёт, ссылки остаются прежними.
Навсегда и с сохранением метода: POST останется POST.
301 переносит вес страницы на новый адрес и кэшируется надолго; 302 говорит «пока здесь», ссылки переносить не нужно; 308 — тот же 301, но сохраняет метод запроса, поэтому подходит для API.
401 · 403
ДоступСервер не знает, кто вы: токена нет или он истёк.
Сервер знает вас, но прав на действие нет.
401 — сервер не знает, кто вы: нужен вход или свежий токен. 403 — знает, но не даёт: дело в правах, и повторный вход ничего не изменит.
200 · 204
УспехУспех, тело в ответе есть — его и читают.
Успех без тела: проверять только код ответа.
200 отдаёт тело ответа, 204 — успех без тела. Клиент, который ждёт JSON от 204, падает на разборе пустой строки.
400 · 422
ДанныеСломан сам запрос: синтаксис, формат, пропущенный параметр.
Запрос понят, но значения не проходят проверку.
400 — сломан сам запрос: синтаксис, формат, отсутствующий параметр. 422 — запрос понят, но данные не проходят проверку: почта без собаки, отрицательное количество.
502 · 504
ШлюзАпстрим ответил чем-то невнятным — чаще всего он упал.
Апстрим не ответил вовремя — он жив, но слишком медленный.
502 — вышестоящий сервер ответил чем-то невнятным или не ответил вовсе; 504 — ответ не пришёл за отведённое время. Первое чаще про упавшее приложение, второе — про медленное.
О кодах HTTP
1xx — информационные
Промежуточные2xx — успех
Всё хорошо3xx — перенаправление
Редирект4xx — ошибка клиента
Виноват запрос5xx — ошибка сервера
Виноват серверКто виноват
Быстрое правилоЧастые вопросы
Похожие инструменты
Очистка и разбор ссылки
Проверка IP и CIDR
Декодер JWT
JSON Форматтер
Обновлено