Kubernetes の 422 エラー:原因と解決策

冒頭まとめ Kubernetes の 422 Unprocessable Entity は、区分が Invalid のエラーです。意味は明快で、内容は読めたが、検証を通らなかったという状態を指します。 このエラーの扱いやすさは、応答の details.causes にあります。実装を読むと、検証のエラー一覧がそのまま causes に変換され、各要素に どのフィールドか(field) と なぜ駄目か(reason) が入ります。reason に入る値は決まっていて、必須項目の欠落なら FieldValueRequired、値が不正なら FieldValueInvalid、対応していない値なら FieldValueNotSupported、禁止された操作なら FieldValueForbidden といった具合です。つまり、推測は不要です。どこがなぜ駄目かは応答に書かれています。 もう1つ、実務で最も誤解されている点があります。知らないフィールドを書いても 422 にはなりません。公式文書には、検証の水準を厳格にした場合、未知または重複したフィールドを検出すると 400 Bad Request で拒否する、と明記されています。さらに但し書きとして、既知のフィールドに型の違う値を入れた場合も 400 になる、とも書かれています。 したがって境界はこうなります。読めなかったのが 400、読めたが内容が通らなかったのが 422。綴りを間違えた、型を間違えた、というよくある失敗は 400 側に落ちます。422 が返っているなら、書式の問題ではなく意味の問題です。 エラーの概要 応答の構造は次の形です。details.causes が本体で、message はその要約にすぎません。 { "kind": "Status", "status": "Failure", "message": "Deployment.apps \"web\" is invalid: spec.selector: Invalid value: ...: field is immutable", "reason": "Invalid", "details": { "group": "apps", "kind": "Deployment", "name": "web", "causes": [ { "reason": "FieldValueInvalid", "field": "spec.selector", "message": "Invalid value: ...: field is immutable" } ] }, "code": 422 } kubectl からの見え方には特徴があります。実装を読むと、区分が Invalid の場合だけ専用の整形が行われ、他のエラーのような Error from server (...) の形にはなりません。 ...

2026年8月3日 · ErrorLog

OpenAI API の 422 エラー:原因と解決策

冒頭まとめ OpenAI API の 422 には、他のコードと違う特殊な事情があります。公式の API エラー一覧に、422 の項目がありません。401、403、404、429、500、503 には説明がありますが、422 は載っていません。 定義があるのは、公式のソフトウェア開発キット側です。ライブラリのエラー区分の表に UnprocessableEntityError があり、説明は「形式は正しいにもかかわらず要求を処理できなかった」、対処は「もう一度試すこと」となっています。状態コードの対応表でも 422 はこの区分に割り当てられています。 つまり 422 は、API 側のエラーとしてではなく、クライアント側の受け取り方として定義されているわけです。 これが実務で意味を持ちます。開発キットは、接続先が OpenAI 本体かどうかに関係なく、422 を受け取れば同じ例外を投げます。そして OpenAI 互換をうたうサーバーの多くは、入力の検証に失敗したとき 422 を返します。 したがって、422 を見たときに最初に疑うべきは、自分の要求内容ではなく接続先です。応答本文の形を見れば、どちらが返したかはすぐに分かります。 エラーの概要 OpenAI 本体のエラー応答は、常にこの構造です。 { "error": { "message": "...", "type": "invalid_request_error", "param": "messages", "code": "..." } } 一方、422 を返す互換サーバーの多くは、次の構造を返します。 { "detail": [ { "type": "string_type", "loc": ["body", "input", "str"], "msg": "Input should be a valid string", "input": [[2149, 87515, 1764, 374]], "url": "https://errors.pydantic.dev/2.5/v/string_type" } ] } error オブジェクトではなく detail 配列です。項目の名前もまったく違います。これは、多くの互換サーバーが特定のフレームワークの上に作られており、その検証機構がこの形式でエラーを返すためです。末尾に検証ライブラリの説明への URL が入る点も特徴的です。 紛らわしいのは、どちらの場合も開発キットの例外名は同じになることです。UnprocessableEntityError という名前を見て「OpenAI が返した」と判断してはいけません。 ...

2026年8月3日 · ErrorLog

GCP の 422 エラー:原因と解決策

冒頭まとめ 先に結論を述べます。GCP の窓口は、検証に落ちた要求に対して 422 を返しません。Google が公開しているエラー区分の定義ファイルには17の区分があり、それぞれに対応する HTTP の状態コードが併記されていますが、422 は1か所も出てきません。 代わりに使われるのは 400 です。しかも、400 に対応する区分は1つではなく3つあります。引数が不正な場合、対象の現在の状態がその操作を許さない場合、そして値が許容範囲の外にある場合です。他のサービスが 400 と 422 で表現し分けている区別を、GCP は状態コードではなく区分名で表現している、と考えると分かりやすくなります。 したがって、GCP で入力の誤りを追うときに見るべきは、状態コードではなく応答に含まれる区分名です。ここを読まないと、400 が返ってきたという事実だけでは原因を1つに絞れません。 そして、実際に GCP の宛先から 422 を受け取った場合、それを作ったのは GCP の窓口ではありません。前段のプロキシか、GCP 上で動いている自作あるいは第三者のアプリケーションです。この場合、GCP の設定を調べても答えは出ません。 エラーの概要 区分と状態コードの対応は、定義ファイルにそのまま書かれています。検証に関わる3つを抜き出すと、次のようになります。 引数が不正な場合の区分は、対応する状態コードが 400 です。定義の説明では、系の状態に関係なく問題のある引数、たとえば形式の壊れた名前などを指す、とされています。 対象の状態が操作を許さない場合の区分も、対応は 400 です。空でないディレクトリを削除しようとした場合が例として挙げられており、系の状態が変われば成功しうる、という性質を持ちます。 値が許容範囲の外にある場合の区分も、対応は 400 です。読み取りの開始位置が終端を越えている場合などが該当します。 つまり、応答だけを見ると次の形になり、code の値は3つとも同じです。 { "error": { "code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT" } } 区別できるのは status の値だけです。ここが INVALID_ARGUMENT なのか FAILED_PRECONDITION なのか OUT_OF_RANGE なのかで、次にやることが変わります。 まず最初に:statusの値を読む 第一に、状態コードが 400 であることを確認します。GCP で入力の誤りを疑う場面では、まずここに落ちてきます。 第二に、status の値を読みます。INVALID_ARGUMENT なら送った値そのものが不正で、何度送っても同じです。FAILED_PRECONDITION なら値は正しく、対象の現在の状態が問題です。状態を整えれば同じ要求が通ります。OUT_OF_RANGE なら、値の形式は正しいが範囲の外です。 ...

2026年7月29日 · ErrorLog

Terraform の 422 エラー:原因と解決策

冒頭まとめ Terraform で 422 Unprocessable Entity を受け取ったとき、まず押さえるべきことがあります。このエラーは Terraform が作ったものではありません。Terraform 本体には、要求の内容を検証して 422 を返す仕組みがありません。目にする 422 は、必ずどこかから中継されたものです。 出どころは2つに分かれます。プロバイダが相手先の窓口を叩いた結果として返ってきたものと、HCP Terraform や Terraform Enterprise の窓口を直接叩いた結果として返ってきたものです。前者の場合、応答の中身は相手先の流儀に従います。GitHub の窓口なら GitHub の書式、別のサービスならそのサービスの書式です。したがって、読み方は相手先の規則で決まります。Terraform の文書をいくら読んでも、応答の中身の意味は書かれていません。 もう1つ、共通する性質があります。Terraform の各層は、422 を再試行しません。レジストリ向けの通信で使われている仕組みは、再試行の対象を429と、501を除く500番台に限っています。AWS 向けの実装が再試行の対象として定義しているのも 500・502・503・504 です。どこにも 422 は含まれていません。これは怠慢ではなく設計です。要求を直さない限り結果が変わらないエラーなので、送り直す意味がありません。 エラーの概要 プロバイダ経由の場合、相手先の応答がそのまま、あるいは整形されて表示されます。GitHub を相手にした場合の例です。 Error: PATCH https://api.github.com/repos/example/sample: 422 Validation Failed [{Resource:Repository Field:default_branch Code:invalid Message:Cannot update default branch for an empty repository.}] 同じ相手先でも、詳細が空のことがあります。この場合、手がかりは短い文言だけです。 { "message": "Validation Failed", "errors": [], "documentation_url": "https://docs.github.com/rest/reference/repos#update-a-repository" } 別のサービスを相手にした場合は、書式が変わります。 Bad response statusCode [422]. Status [422 Unprocessable Entity]. Body: [baseType=error, code=InvalidBodyContent, message=must have at least one node pool] HCP Terraform の窓口を直接叩いた場合は、また別の形になります。整形の規約に沿った構造で、status と title と detail が並びます。 ...

2026年7月29日 · ErrorLog

GitLab の 422 エラー:原因と解決策

エラーの概要 GitLabの422エラーは「Unprocessable Entity」を意味し、リクエスト自体は正しく到達したものの、送信されたデータが検証ルールを満たしていないことを示します。プロジェクト作成、マージリクエスト、イシューなどのAPI操作で頻繁に発生し、GitLabサーバー側がデータの内容を受け入れられない状態です。 実際のエラーメッセージ例 GitLabのAPI経由で発生した422エラーの典型的なレスポンスは以下のようなJSON形式です。 { "message": "422 Unprocessable Entity", "error": "Validation failed", "errors": { "title": ["can't be blank"], "description": ["is invalid"] } } ブラウザのWebUIで遭遇した場合のエラー表示例: 422 Unprocessable Entity Failed to create merge request: Title can't be blank よくある原因と解決手順 原因1:マージリクエストのタイトルが空白になっている マージリクエスト作成時にtitleフィールドが空文字列または省略されると、GitLabの検証ルールに違反して422エラーが発生します。GitLab APIではtitleが必須フィールドとして定義されており、どのような値でも良いわけではなく「空でない文字列」という最小限の検証を通す必要があります。 修正前(エラーが起きるコード): curl --request POST \ --header "PRIVATE-TOKEN: <your-token>" \ "https://<your-gitlab-instance>/api/v4/projects/<project-id>/merge_requests" \ --data "source_branch=feature-branch&target_branch=main&title=" 修正後: curl --request POST \ --header "PRIVATE-TOKEN: <your-token>" \ "https://<your-gitlab-instance>/api/v4/projects/<project-id>/merge_requests" \ --data "source_branch=feature-branch&target_branch=main&title=Add new feature" 原因2:プロジェクト名がグループのルールに違反している グループレベルで名前の長さ制限や命名規則が設定されている場合、その規則に適合しないプロジェクト名で作成しようとすると422エラーが返されます。特に大規模な組織では、プロジェクト命名を統一するためにグループ管理者が検証ルールを配置していることがあります。 修正前(エラーが起きるコード): curl --request POST \ --header "PRIVATE-TOKEN: <your-token>" \ "https://<your-gitlab-instance>/api/v4/projects" \ --data "name=ThisProjectNameIsWayTooLongAndViolatesGroupNameLengthRestrictions&namespace_id=<group-id>" 修正後: ...

2026年6月13日 · ErrorLog

AWS の 422 エラー:原因と解決策

エラーの概要 AWS における 422 Unprocessable Entity は、HTTP リクエストの形式は正しいが、含まれるデータが処理不可能または検証に失敗したことを示します。CloudFormation、API Gateway、Lambda、EventBridge、DynamoDB など複数のAWSサービスで発生する可能性があります。このエラーが返されるのは、リクエストの構文は valid だが、ビジネスロジックレベルでの矛盾や制約違反があるためです。 実際のエラーメッセージ例 CloudFormation で展開時に発生する 422 エラー: { "message": "Template error: instance of Fn::GetAtt references undefined resource", "code": "ValidationError", "statusCode": 422 } API Gateway を経由した Lambda 呼び出しでのエラーレスポンス: { "message": "Invalid request body: required field 'userId' is missing", "errorType": "UnprocessableEntity", "statusCode": 422 } よくある原因と解決手順 原因1: CloudFormation テンプレートのリソース参照ミス CloudFormation スタックをデプロイする際、テンプレート内で存在しないリソースを参照している場合に 422 が返されます。Fn::GetAtt や Ref を使用してリソース間の依存関係を記述しているとき、参照先のリソース名が誤っていたり、そのリソースが定義されていなかったりすることが原因です。 Before(エラーが発生する例): Resources: MyLambdaRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: lambda.amazonaws.com Action: sts:AssumeRole MyLambda: Type: AWS::Lambda::Function Properties: Runtime: python3.11 Handler: index.handler Role: !GetAtt NonExistentRole.Arn Code: ZipFile: | def handler(event, context): return 'Hello' After(修正後): ...

2026年5月24日 · ErrorLog

Docker の 422 エラー:原因と解決策

エラーの概要 Dockerで 422 エラーが発生するのは、Docker APIまたはコンテナレジストリへのリクエストが構文的には正しいものの、含まれるデータが処理要件を満たしていない場合です。Docker Daemon、Docker Compose、レジストリ APIとの通信時にこのエラーが返される典型的なシナリオは、不正なイメージタグ指定、設定値の型違反、あるいは APIスキーマの検証失敗です。 実際のエラーメッセージ例 { "message": "invalid tag format", "code": 422 } $ docker push myregistry.example.com/app:invalid@tag Error response from daemon: invalid tag format # docker-compose.yml でエラーが発生 ERROR: The Compose file is invalid because: Service 'web' has invalid value for ports: ports must be an integer or string よくある原因と解決手順 1. イメージタグの形式が不正 Dockerレジストリ APIは RFC 6391 に基づいたタグ形式を要求します。許可されない文字(@や大文字の混在)が含まれている場合に 422 が返されます。 Before(エラーが起きる例): docker tag myimage:latest myregistry.example.com/app:INVALID@latest docker push myregistry.example.com/app:INVALID@latest # Error: invalid tag format After(修正後): # タグは小文字のみで、「:」で区切る docker tag myimage:latest myregistry.example.com/app:v1.0.0 docker push myregistry.example.com/app:v1.0.0 2. docker-compose.yml の設定値の型違反 ports、mem_limit、cpu_sharesなど、数値型を期待するフィールドに文字列を指定するとバリデーション失敗で 422 が返されます。 ...

2026年1月1日 · ErrorLog

GitHub API の 422 エラー:原因と解決策

冒頭まとめ GitHub API の 422 Unprocessable Entity は、リクエストが JSON として正しく読めたうえで、中身がそのエンドポイントの検証ルールに通らなかったことを示すコードです。GitHub 公式の API 定義(OpenAPI)で数えると、422 を応答として定義するエンドポイントは308あり、全コードの中で最多です。つまり422は特別な異常ではなく、「パラメータを持つ操作の、最もありふれた失敗の形」です。 調査の核は、応答の errors 配列を読むことに尽きます。公式文書のとおり、配列の各要素は resource(どの種類の対象か)、field(どの項目か)、code(何が悪いか)を持ち、code の値は公式に定義されています。missing_field は必須項目の未設定、invalid は項目の形式の不正、already_exists は同じ値を持つ対象が既に存在、missing は指した対象が存在しない、unprocessable は入力を処理できない、そして custom の場合は必ず message が付き、その文言をそのまま読みます。code と field が分かれば、原因はほぼ確定します。 境界も先に引いておきます。本文が JSON として壊れている場合は 400(Problems parsing JSON)で、422の手前の問題です。対象の「今の状態」との矛盾(sha の不一致、空リポジトリ)は 409 です。また、422は形式的な性質として、リクエストを修正しない限り何度送っても同じ結果になります。GitHub 公式の Octokit の retry プラグインも422を再試行の対象外としており、422への正しい反応は再送ではなく修正です。 エラーの概要 422 の応答本文は、公式の API 定義に Validation Error というスキーマとして定義されています。message と documentation_url が必ず含まれ、多くの場合 errors 配列が付きます。配列の各要素で必須なのは code だけで、resource・field・value(実際に送られた値)は項目に応じて付きます。 { "message": "Validation Failed", "errors": [ { "resource": "Issue", "field": "title", "code": "missing_field" } ], "documentation_url": "https://docs.github.com/rest/issues/issues#create-an-issue" } この例は公式文書に掲載されているもので、「Issue の title が未設定」と一行で読めます。もう1つ、errors が文字列の配列だけの簡易な形(Validation Error Simple)も公式定義に存在し、この場合は文字列の文言をそのまま読みます。 ...

2026年1月1日 · ErrorLog