422 Unprocessable Entity
Client Error
The request was well-formed but the server cannot process it due to semantic errors. The data is syntactically valid for its content type but violates business rules. 422 was added in WebDAV (RFC 4918) and adopted broadly by REST APIs to distinguish syntax problems (400) from value problems. A 422 response should include a structured error body describing which field failed and why, so clients can show inline validation messages without parsing free-text errors.
When does this happen?
Return 422 when the request body is parseable JSON or XML, the Content-Type is correct, the user is authenticated, but the values fail business validation. Common cases include required fields missing, enum values outside the allowed set, foreign-key references to resources that do not exist, or constraint violations like a unique email already in use. A good 422 response is structured: most modern APIs return an errors array with a path and a code for each failed field, allowing the frontend to attach the message to the right input. Browsers do not handle 422 specially. Your client code must interpret it. Distinguish 422 from 400 carefully: if the body could not even be parsed, return 400; if the body parsed but failed your rules, return 422. Conflating them makes life harder for SDK authors and for retry logic, since 400 implies the client should not retry with the same payload while 422 implies it should fix specific fields.
Common causes
- Required field missing from the request body. The JSON parsed but a mandatory key is absent.
- Field value out of the allowed range. Age below zero, currency outside ISO 4217, country code not in the list.
- Invalid email, URL, UUID, or other formatted string. Passes type checks but fails format validation.
- Foreign-key reference to a resource that does not exist. E.g. user_id pointing at a deleted user.
- Unique constraint violation. An email or username already in use by another account.
- Cross-field validation failure. End_date before start_date, or password matching one of the user's previous passwords.
- Enum value not in the allowed set. Status: "shipd" instead of "shipped".
- Business rule unmet. E.g. attempting to publish a post without all required metadata.
How to fix it
- Read the error response. Most APIs return a structured list of field-level errors with codes you can react to programmatically.
- Validate input on the client before sending. Most 422s can be caught with JSON Schema or a form-validation library before they ever leave the browser.
- Check the API documentation or OpenAPI spec for required fields, allowed values, and constraints.
- Distinguish 422 from 400 in your handlers if you control the API. Clients depend on this to choose retry behavior.
- For unique-constraint violations, surface the conflict inline ("this email is already in use") rather than a generic validation error.
- Pre-fetch related resources (foreign keys) and confirm they exist before submitting. Saves a 422 round-trip.
- Handle the field-level errors in your client by mapping each error path to the right form input, so users see the message next to the broken field.
Real-world examples
- Client POSTs {"email":"not-an-email","age":-3} to a user registration endpoint.
- Server returns 422 with errors: [{path:"email",code:"invalid_format"},{path:"age",code:"out_of_range"}]. Frontend highlights both fields inline.
- API client tries to create an order with product_id referring to a deleted product.
- Server returns 422 with {"errors":[{"path":"product_id","code":"not_found"}]}. Client refreshes its product list and retries.
- User submits a signup form with an email already in use.
- Server returns 422 with {"errors":[{"path":"email","code":"taken"}]}. UI shows "This email is already registered" next to the email field.
- API call to create an event with end_date earlier than start_date.
- Server returns 422 with a cross-field error pointing at end_date. UI updates the date picker to flag the inconsistency.
- Client passes status: "shipd" (typo) to an enum field expecting "shipped".
- Server returns 422 with {"errors":[{"path":"status","code":"invalid_enum","allowed":["pending","shipped","delivered"]}]}.
How it differs from related codes
HTTP 400
400 is about the request being unparseable or malformed. 422 means the request parsed cleanly but specific values are invalid. Retry behavior differs. 400 means "do not retry as-is," 422 means "fix these fields and retry."
HTTP 415
415 means the Content-Type was wrong. 422 means the Content-Type was right but the data inside failed validation. You cannot get 422 without first passing the 415 check.
HTTP 409
409 is for state-conflict errors. E.g. trying to update a resource that has been modified by someone else. 422 is for input that fails validation against the current state.
Related status codes
See HTTP 422 in your redirect chains?