422 Unprocessable Entity: что означает и как исправить
422 Unprocessable Entity означает, что запрос был синтаксически валиден, и сервер прекрасно его понял, но данные внутри него не проходят проверку валидации. Это код для "я прочитал ваш запрос нормально, значения в нем неверны", в противоположность запросу, который сервер вообще не смог разобрать.
Что означает 422 Unprocessable Entity
422 возник в WebDAV (RFC 4918) и позже был широко принят REST API как стандартный ответ для провалов семантической проверки. RFC 9110 официально переименовал текст статуса в 422 Unprocessable Content, убрав специфичную для WebDAV формулировку "Entity", хотя оба названия описывают идентичный код состояния, и "Unprocessable Entity" остается гораздо более распространенным ярлыком в настройках фреймворков по умолчанию и документации API. Важное различие - синтаксис против семантики: JSON разобрался корректно, тип каждого обязательного поля совпадает, и запрос корректно сформирован по каждому структурному правилу, но значение внутри него нарушает бизнес-правило, например адрес электронной почты в неверном формате, дата в прошлом там, где требуется будущая дата, либо поле, ссылающееся на несуществующую запись.
Как проявляется ошибка
422 почти никогда не появляется как ошибка навигации браузера, поскольку это преимущественно ответ API, а не то, что напрямую вызывает ссылка или отправка формы; она проявляется на вкладке сети, в тосте с ошибкой либо в провалившемся утверждении теста. Из командной строки полезная деталь находится в теле ответа:
curl -i -X POST https://api.example.com/v1/users -H "Content-Type: application/json" -d '{"email": "not-an-email", "age": -5}'
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{"errors": {"email": ["is not a valid email"], "age": ["must be greater than 0"]}}
Большинство хорошо построенных API возвращают структурированное тело ошибки вместе с 422, точно называя, какое поле провалилось и почему, а не оставляют вызывающего гадать по одному лишь коду состояния.
Что вызывает 422 Unprocessable Entity
- Ошибки валидации в REST API. Приложения на Rails обычно автоматически возвращают 422, когда модель ActiveRecord проваливает валидацию при создании или обновлении. Валидация запросов форм в Laravel по умолчанию возвращает 422 для проваленных правил. FastAPI, построенный на Pydantic, возвращает 422 всякий раз, когда данные запроса проваливают проверку типа или ограничения модели Pydantic, поэтому это один из наиболее часто встречающихся кодов состояния конкретно в проектах на FastAPI.
- Поле с правильным типом, но недопустимым значением. Строка там, где ожидалась строка, но проваливающая проверку формата, лимит длины либо список допустимых значений.
- Ссылка на что-то несуществующее. Внешний ключ, id пользователя либо slug в теле запроса, синтаксически корректный, но не соответствующий никакой реальной записи.
- Бизнес-правила сверх простой проверки полей. Промокод, синтаксически валидный, но истекший, либо количество, являющееся валидным целым числом, но превышающее доступный запас.
- Полностью отсутствующее обязательное поле. В зависимости от фреймворка отсутствующее обязательное поле может вернуть 422 вместо 400, поскольку запрос разбирается нормально, ему просто не хватает значения, которое требует слой валидации.
422 против 400
Граница - это синтаксис против семантики. 400 Bad Request означает, что сервер вообще не смог разобрать запрос, например некорректный JSON или тело, невалидное по какому-либо структурному правилу. 422 означает, что запрос разобрался без каких-либо проблем, и каждое поле правильного типа, но значение внутри него проваливает правило, которое приложение проверяет уже после разбора. На практике многие API размывают это различие и используют 400 для обоих случаев, что оправданно, но менее точно; клиент, интегрирующийся с API, должен читать тело ответа, а не полагаться только на код состояния, чтобы точно знать, что именно провалилось.
Как исправить ошибку 422
Если вы клиент, вызывающий API
- Прочитайте тело ответа, а не только код состояния. Ответ 422 у хорошо построенного API называет конкретное поле и правило, которое провалилось, что точно говорит, что нужно исправить, без дальнейших догадок.
- Проверьте поле по документированным ограничениям API, таким как формат, длина и допустимые значения, поскольку это бизнес-правила, которые одна лишь схема вам не покажет.
- Относитесь к 422 как к сигналу исправить данные, а не повторять запрос без изменений. Повторная отправка немодифицированного запроса, провалившего валидацию, будет проваливаться одинаково каждый раз; хорошо ведущий себя клиент должен показать конкретную ошибку пользователю, а не молча повторять попытку.
Если вы администрируете API
- Всегда возвращайте структурированное тело ошибки вместе с 422, называя поле и правило, которое провалилось, а не голый код состояния без объяснения.
- Держите сообщения об ошибках валидации конкретными и практичными, например "email must be a valid address" вместо общего "validation failed", вынуждающего вызывающего гадать, какое из нескольких полей было проблемой.
- Осознанно решите между 400 и 422 для своего API и задокументируйте этот выбор, чтобы интеграторы могли строить надежную обработку ошибок вместо того, чтобы относиться к каждому 4xx одинаково.
- Логируйте прошедшие валидацию, но отклоненные полезные нагрузки во время разработки, чтобы ловить случаи, когда ваш собственный клиентский код стабильно отправляет данные, проваливающие валидацию, что часто указывает на несовпадение между клиентом и реальными правилами API.
Как клиенту следует обрабатывать ответ 422
Хорошо спроектированный клиент относится к 422 как к принципиально отличному от ошибки 5xx или сетевого сбоя: это означает, что сервер здоров и работает правильно, а вызывающий отправил что-то, что сервер никогда не примет в таком виде. Правильная реакция - разобрать тело ошибки, сопоставить каждое провалившееся поле обратно с формой или вводом, породившим его, и показать пользователю что-то практичное, а не повторять попытку с задержкой так, как вы делали бы для таймаута или 503. Автоматизированные тесты, проверяющие слой валидации API, должны проверять конкретное возвращаемое тело ошибки, а не только статус 422, поскольку именно это подтверждает корректность самой логики валидации.
Как предотвратить, чтобы 422 не остались незамеченными
Правило валидации, неожиданно изменившееся - будь то из-за деплоя, обновления сторонней библиотеки либо миграции схемы, - может незаметно начать отклонять запросы, которые раньше проходили успешно. HTTP-проверка, отправляющая заведомо корректную полезную нагрузку и проверяющая ожидаемый код состояния, ловит такую регрессию сразу после деплоя. Для API с несколькими эндпоинтами либо полезной нагрузкой, которую один лишь код состояния полностью не проверит, мониторинг API, также проверяющий тело ответа, подтверждает саму логику валидации, а не только то, что сервер достижим.
Похожие ошибки
См. 400 Bad Request - для случая непарсящегося запроса, с которым это руководство проводит сравнение, обзор 4xx - для более широкого семейства, и 401 Unauthorized и 405 Method Not Allowed в других руководствах этой партии.
Часто задаваемые вопросы
422 Unprocessable Entity - это то же самое, что 422 Unprocessable Content?
Да. RFC 9110 переименовал поясняющую фразу в Unprocessable Content, но это тот же код состояния с тем же значением; большинство фреймворков и документации API до сих пор используют более старую формулировку Unprocessable Entity.
Почему мое приложение на FastAPI возвращает 422 для отсутствующего поля?
FastAPI автоматически проверяет данные запроса по вашим моделям Pydantic, и отсутствующее обязательное поле либо поле неверного типа проваливает эту проверку и возвращает 422 с телом, точно описывающим, какое поле и правило провалились.
Стоит ли повторять запрос, получивший 422?
Только после изменения данных, проваливших валидацию. Повторение идентичного запроса будет каждый раз давать идентичный 422, поскольку сервер правильно и стабильно отклоняет один и тот же невалидный ввод.
В чем разница между 422 и 400 на практике?
400 - для запроса, который сервер вообще не может разобрать. 422 - для запроса, который разбирается нормально, но содержит значение, проваливающее правило валидации или бизнес-правило. Многие реальные API используют 400 для обоих случаев, так что всегда проверяйте документированное соглашение конкретного API, который вы вызываете.
Может ли 422 означать баг на сервере?
Может, если само правило валидации неверно, например отклоняет действительно валидный формат email. Но 422 по замыслу означает, что сервер работает как задумано и возражает против данных, поэтому исследуйте само правило валидации, прежде чем предполагать, что оно сломано.