HTTP 422 Unprocessable Entity — 검증 실패·400과의 차이 원인·해결
회원가입 폼을 제출했더니 422 Unprocessable Entity가 돌아온다. JSON 형식도 맞고 서버에 잘 도달했는데 거절당했다. 422는 "요청 형식(구문)은 제대로지만, 그 내용을 의미상 처리할 수 없다"는 뜻이다. 대부분 입력 검증 실패에서 만난다. 이메일 형식이 틀렸거나, 필수 항목이 비었거나, 이미 가입된 이메일을 다시 보냈을 때다. 자주 헷갈리는 400 Bad Request와는 결정적으로 다르다. 400은 형식 자체가 깨진 것이고, 422는 형식은 맞는데 값이 규칙에 안 맞는 것이다. 이 글은 422의 의미, 400과의 차이, 응답을 읽고 고치는 법을 정리한다.

이 글의 구성
🔎 422 Unprocessable Entity의 의미
422는 4xx, 클라이언트 요청에 문제가 있다는 묶음이다. 다만 그 문제가 "형식"이 아니라 "의미"에 있다. 서버는 요청 구문을 이해했고, Content-Type도 알아들었다. 그런데 그 안에 담긴 내용(지시)을 따를 수가 없는 상태다. 가장 흔한 경우가 입력 검증 실패다.
이 코드는 원래 WebDAV 명세(RFC 4918)에서 나왔지만, 지금은 일반 HTTP 명세(RFC 9110)에 포함돼 Unprocessable Content라는 이름으로 정리됐다. 번호 422는 그대로다. REST API에서 폼·데이터 검증 결과를 돌려줄 때 널리 쓰여, 백엔드를 다루면 자주 마주친다.
핵심 — 형식은 통과, 내용에서 막힘
422는 "보낸 게 깨진 게 아니라, 규칙에 안 맞는다"는 신호다. JSON은 멀쩡히 파싱됐고 필드 구조도 맞는데, 이메일 형식이 아니거나 필수 값이 비었거나 비즈니스 규칙에 어긋난 것이다. 그래서 422 응답에는 보통 "어떤 필드가 왜 틀렸는지"가 본문에 함께 담긴다. 그 본문이 해결의 지도다.
⚖️ 400 Bad Request와의 핵심 차이
422를 이해하는 가장 빠른 길은 400과 나란히 두는 것이다. 둘 다 4xx 클라이언트 오류지만, 막히는 지점이 다르다.
| 구분 | 400 Bad Request | 422 Unprocessable |
|---|---|---|
| 막히는 곳 | 구문·형식 자체가 깨짐 | 구문은 맞고 의미가 안 맞음 |
| 예시 | JSON 문법 오류, 깨진 본문 | 이메일 형식 틀림, 필수값 누락 |
| 서버 상태 | 파싱조차 못 함 | 파싱은 됐고 검증에서 실패 |
비유하면, 400은 글씨를 못 알아볼 정도로 서류가 엉망인 것이고, 422는 글씨는 또박또박한데 칸에 잘못된 값을 적은 것이다. 그래서 400은 요청을 다시 만들어야 하고, 422는 값만 규칙에 맞게 고치면 된다. 다만 현실에서는 프레임워크마다 관습이 갈린다. Rails·Laravel 같은 곳은 검증 실패에 422를 쓰고, 어떤 API는 같은 상황에 400을 쓴다. 그래서 내가 쓰는 API가 검증 실패를 무엇으로 돌려주는지는 문서로 확인하는 게 안전하다.
🧩 자주 나오는 발생 원인 4가지
원인 1 — 필수 필드 누락·형식 오류
가장 흔하다. 필수 항목을 빼먹었거나, 이메일·전화번호·날짜 형식이 규칙과 다른 경우다. 구조는 맞지만 값이 검증을 통과하지 못한다.
원인 2 — 값의 범위·길이 위반
나이에 음수, 비밀번호가 최소 길이 미달, 수량이 허용 범위를 벗어난 경우다. 타입은 맞는데 값이 제약 조건을 어긴 것이다.
원인 3 — 비즈니스 규칙 위반
이미 가입된 이메일로 또 가입, 재고보다 많은 수량 주문처럼 데이터는 멀쩡한데 업무 규칙에 어긋난 경우다. 형식 검증을 넘어 도메인 검증에서 막힌다.
원인 4 — 잘못된 값 타입·참조
숫자 자리에 문자열을 넣었거나, 존재하지 않는 ID를 참조한 경우다. JSON 문법은 맞아 파싱은 되지만, 서버 스키마 기준으로는 처리할 수 없다.
💻 재현과 응답 본문 읽기
422는 일부러 규칙에 안 맞는 값을 보내면 재현된다. 형식은 올바른 JSON이되 값이 검증을 통과 못 하도록 만든다.
# 형식은 맞지만 이메일이 규칙 위반 → 422
curl -i -X POST https://example.com/users \
-H 'Content-Type: application/json' \
-d '{"email": "not-an-email", "age": -5}'
# 응답 — 어떤 필드가 왜 틀렸는지 본문에 담긴다
HTTP/1.1 422 Unprocessable Entity
{
"errors": {
"email": ["유효한 이메일 형식이 아닙니다"],
"age": ["0 이상이어야 합니다"]
}
}
참고로 같은 잘못된 입력이라도 검증 실패에 422를 쓰는 API에서만 422가 떨어지고, 400으로 응답하는 API도 있다. 그래서 코드 번호보다 응답 본문이 더 믿을 단서다. 422 디버깅의 핵심은 상태 코드가 아니라 응답 본문이다. 잘 만든 API는 어떤 필드가 어떤 규칙을 어겼는지 구체적으로 알려준다. 콘솔이나 네트워크 탭에서 응답 본문을 펼쳐 보면, 고쳐야 할 입력이 바로 드러난다. 상태 코드만 보고 "또 422네" 하고 넘기면 정작 단서를 놓친다.
🛠 해결 방법과 설계 원칙
422는 거의 항상 "보낸 값을 규칙에 맞게 고치면" 풀린다. 호출하는 쪽과 만드는 쪽의 할 일이 다르다.
| 입장 | 할 일 |
|---|---|
| 호출하는 쪽 | 응답 본문의 검증 에러를 읽고 해당 필드 값 수정 |
| 프론트엔드 | 전송 전 클라이언트 검증으로 잘못된 입력 미리 차단 |
| 백엔드 | 필드별 구체적 에러 메시지를 일관된 형식으로 반환 |
| API 사용자 | 문서의 스키마·제약 조건 확인 후 요청 구성 |
단계별 진단 절차
설계 관점에서 한 가지 더. 422 응답은 상태 코드만큼이나 본문이 중요하다. 어떤 필드가 왜 막혔는지를 일관된 구조로 돌려주면, 클라이언트가 사용자에게 친절한 안내를 띄울 수 있다. 그냥 422만 던지고 본문이 비어 있으면, 호출하는 쪽은 무엇을 고쳐야 할지 몰라 헤맨다.
400은 서류가 깨진 것, 422는 칸에 잘못된 값을 적은 것이다. 422를 만나면 상태 코드가 아니라 응답 본문을 읽어라.
— 형식이 아니라 내용을 고친다
💬 자주 묻는 질문 5가지
Q1JSON 형식은 맞는데 왜 422가 나죠?
바로 그 점이 422의 핵심입니다. 형식(구문)은 맞아 파싱은 됐지만, 값이 검증 규칙에 어긋난 것입니다. 이메일 형식이 틀렸거나 필수값이 비었거나 범위를 벗어난 경우죠. 응답 본문을 보면 어떤 필드가 문제인지 알려줍니다.
Q2400이랑 422는 뭐가 다른가요?
400은 요청 구문·형식 자체가 깨져 파싱조차 못 하는 것이고, 422는 형식은 맞는데 의미(값)가 규칙에 안 맞는 것입니다. 400은 요청을 다시 만들어야 하고, 422는 값만 규칙에 맞게 고치면 됩니다.
Q3검증 실패에 400을 쓰는 API도 있던데요?
맞습니다. 프레임워크마다 관습이 다릅니다. Rails·Laravel은 검증 실패에 422를 쓰지만, 어떤 API는 같은 상황에 400을 씁니다. 둘 다 틀린 건 아니에요. 그래서 내가 쓰는 API가 검증 실패를 무엇으로 돌려주는지 문서로 확인하는 게 안전합니다.
Q4응답에 422만 오고 설명이 없어요.
본문 없이 상태 코드만 주는 API는 디버깅이 어렵습니다. 호출하는 입장이라면 문서의 스키마·제약 조건과 대조해 어떤 값이 규칙을 어겼는지 추적해야 합니다. 서버를 만드는 입장이라면, 필드별 에러 메시지를 본문에 일관되게 담아 주는 게 좋은 설계입니다.
Q5중복 가입 같은 것도 422인가요?
비즈니스 규칙 위반도 422로 많이 처리합니다. 이미 가입된 이메일, 재고 초과 주문처럼 데이터 형식은 멀쩡한데 업무 규칙에 어긋난 경우죠. 다만 충돌 상황을 409 Conflict로 구분하는 API도 있으니, 역시 문서 규약을 따르는 게 좋습니다.
📌 결론
422 Unprocessable Entity는 "요청 형식은 맞지만 내용을 의미상 처리할 수 없다"는 신호다. 대부분 입력 검증 실패에서 만나고, 형식이 깨진 400과는 분명히 다르다. 400은 서류가 깨진 것, 422는 칸에 잘못된 값을 적은 것이다.
실무 원칙은 다음과 같다.
📋 400과 구분한다. 형식이 깨졌으면 400, 형식은 맞고 값이 규칙에 안 맞으면 422다. 검증 실패에 무엇을 쓰는지는 API 문서로 확인한다.
🔍 응답 본문을 읽는다. 422 디버깅의 단서는 상태 코드가 아니라 본문의 필드별 검증 에러에 있다.
✅ 값을 고치고 검증을 설계한다. 호출하는 쪽은 규칙에 맞게 값을 수정하고, 만드는 쪽은 필드별 에러 메시지를 일관되게 돌려준다.
422 트러블슈팅 체크리스트
본 글은 HTTP 422 응답의 일반적 의미와 해결 방법을 정리한 자료다. 검증·API 설계 변경은 영향 범위를 확인한 뒤 신중히 적용한다.
#HTTP422 #UnprocessableEntity #422에러 #400과422차이 #입력검증 #유효성검사 #REST API #BadRequest #검증실패 #Rails #Laravel #백엔드 #프론트엔드 #API에러 #웹개발
'IT' 카테고리의 다른 글
| HTTP 408 Request Timeout — 요청 시간 초과·504와의 차이 원인·해결 (0) | 2026.06.28 |
|---|---|
| HTTP 409 Conflict — 충돌·동시 수정·중복 원인·해결 (1) | 2026.06.28 |
| HTTP 413 Payload Too Large — 요청 본문 초과 원인·해결·예방 (0) | 2026.06.28 |
| HTTP 405 Method Not Allowed — 메서드 허용 안 됨 원인·해결·예방 (0) | 2026.06.28 |
| CORS 에러 완전 정리 — 교차 출처 차단 원인·프리플라이트·서버별 해결 (0) | 2026.06.28 |
댓글