422 Unprocessable Content
사용법
422 Unprocessable Content 오류는 서버가 요청을 이해했지만 그 콘텐츠가 의미상 유효하지 않다고 판단했음을 나타냅니다. 콘텐츠 타입은 인식된 상태입니다(그렇지 않다면 415 Unsupported Media Type 오류가 전송됩니다). 문법도 유효합니다(그렇지 않다면 400 Bad Request 오류가 더 적절합니다).
이런 유형의 오류는 요청이 메시지 본문으로 XML 지시 블록을 포함하고 있고, 그 형식이 올바르며 서버도 이해하지만, 논리에 오류가 있어 서버 측 오류로 이어질 때 발생합니다.
참고
요청 본문을 수정하지 않고 422를 재시도하면 같은 오류가 납니다. 클라이언트가 먼저 검증 문제를 고쳐야 합니다. Content-Type이 인식되고 문법도 유효하지만 비즈니스 규칙이나 필드 검증이 데이터를 거부할 때 422를 반환하세요.
SEO 영향
Google 같은 검색 엔진은 422 Unprocessable Content 응답 상태를 가진 URL을 색인하지 않으며, 따라서 과거에 색인되었다가 이 HTTP 상태 코드를 반환하는 URL은 검색 결과에서 제거됩니다.
예시
클라이언트가 XML 문서를 사용해 작업 #100을 시작하라고 요청합니다. 그 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에서는 생성이나 갱신 시 모델 검증이 실패하면 기본적으로 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