422 Unprocessable Content
使い方
422 Unprocessable Content エラーは、サーバーがリクエストを理解したうえで、その内容が意味的に無効だと判断したことを示します。コンテンツタイプは認識されています(そうでなければ 415 Unsupported Media Type エラーが送信されます)。構文も有効です(そうでなければ 400 Bad Request エラーのほうが適切です)。
この種のエラーは、リクエストがメッセージボディとして XML の指示ブロックを含み、それが正しく整形されサーバーに理解されているにもかかわらず、論理上の誤りを含んでいてサーバー側のエラーにつながる場合に発生します。
注意
リクエストボディを修正せずに 422 を再試行しても、同じエラーになります。クライアントはまず検証の問題を修正しなければなりません。Content-Type が認識され構文も有効であるものの、ビジネスルールやフィールドの検証がデータを拒否する場合に 422 を返します。
SEO への影響
Google のような検索エンジンは、422 Unprocessable Content のレスポンスステータスを持つ URL をインデックスしません。したがって、過去にインデックスされていた URL がこの HTTP ステータスコードを返すようになると、検索結果から削除されます。
例
クライアントがタスク #100 の開始を要求するために XML ドキュメントを使用します。この XML ドキュメントはサーバーに認識され、構文的にも正しいものです。サーバーには id=100 のタスクの記録がないため、このリクエストは処理できません。
リクエスト
POST /requests HTTP/1.1
Host: example.com
Content-Type: application/xml
Content-Length: 101
<?xml version="1.0" encoding="utf-8"?>
<request>
<id>100</id>
<action>start</action>
</request>
レスポンス
HTTP/1.1 422 Unprocessable Content
Content-Type: text/html
Content-Length: 150
<html>
<head>
<title>Request Failed</title>
</head>
<body>
<p>Task #100 is not recognized.</p>
</body>
</html>
対処方法
まずレスポンスボディを調べます。ほとんどの API やフレームワークは、どの値がなぜ失敗したかを説明するフィールド単位のエラー詳細を返します。それらのメッセージを使って正確な問題点を特定します。
送信前に、リクエストボディを期待されるスキーマと照らして検証します。一般的なきっかけには、必須フィールドの欠落、誤ったデータ型(API が数値を期待する箇所に文字列を送るなど)、無効なメールアドレスや日付の形式、一意であるべき値の重複、許可された集合の外にある列挙値などがあります。
Content-Type ヘッダーがボディの形式と一致していることを確認します。text/plain のコンテンツタイプで JSON を送ると、多くのサーバーで解析に失敗します。
Laravel では、422 は通常フォームの検証ルールが満たされなかったことを意味します。JSON レスポンスの errors オブジェクトで、失敗したフィールド名と検証メッセージを確認します。Rails では、create や update でのモデル検証の失敗はデフォルトで 422 を返します。詳細は model.errors を調べてください。
GitHub や Shopify のような REST API では、リクエストのペイロードが現在の API バージョンに適合していることを検証します。フィールド名、必須パラメーター、受け入れられる値はバージョン間で変化します。
サーバー側では、無効な各フィールド、拒否された値、期待される形式を列挙した構造化されたエラーレスポンスを返します。「validation failed」といった汎用的なメッセージは、クライアントに推測を強います。
コードリファレンス
.NET
HttpStatusCode.UnprocessableEntity
Rust
http::StatusCode::UNPROCESSABLE_ENTITY
Rails
:unprocessable_entity
Go
http.StatusUnprocessableEntity
Symfony
Response::HTTP_UNPROCESSABLE_ENTITY
Python3.5+
http.HTTPStatus.UNPROCESSABLE_ENTITY
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_UNPROCESSABLE_CONTENT
// deprecated alias: SC_UNPROCESSABLE_ENTITY
Angular
@angular/common/http/HttpStatusCode.UnprocessableEntity