How HTTP Works
4xx · Client error
< HTTP/1.1 422 Unprocessable Content

422 Unprocessable Entity (Unprocessable Content) Explained

422 Unprocessable Content (formerly Unprocessable Entity): the JSON parsed but failed validation. FastAPI, Laravel and Rails errors, 422 vs 400, RFC 9457.

Reviewed 5 min readintermediate4 sourcesTry itMarkdown
Cacheable
Only with explicit freshness
Retry?
No: fix the payload
Usually sent by
Origin app
Spec
RFC 9110 §15.5.21
Often confused with
400, 409
On this page

TL;DR: 422 Unprocessable Content means the server rejected the data in your request, usually because a field failed validation. Read the response body, fix the named field or missing CSRF token, then resend the corrected request.

What you see in your client

The messages and response bodies here are illustrative. Client messages use https://api.example.com/resource; reason phrases and URLs can vary.

  • Axios: AxiosError: Request failed with status code 422 with the default status handling. Inspect error.response.data for the server’s explanation. Axios source.
  • fetch: the promise resolves with response.status === 422 and response.ok === false. Check the status before reading the body; HTTP errors do not enter catch automatically. MDN fetch.
  • Python requests: requests.exceptions.HTTPError: 422 Client Error: Unprocessable Entity for url: https://api.example.com/resource when you call response.raise_for_status(). Requests source.
  • curl -f: curl: (22) The requested URL returned error: 422. Use curl -i without -f while inspecting the error body. curl source.
  • .NET: HttpRequestException with the English message Response status code does not indicate success: 422 (Unprocessable Entity). after EnsureSuccessStatusCode(). Runtime message template.
  • Spring WebClient: WebClientResponseException$UnprocessableEntity: 422 Unprocessable Entity from POST https://api.example.com/resource with retrieve(). Read getResponseBodyAsString(). Spring 6.2 source.
  • Spring RestTemplate (6.2): HttpClientErrorException$UnprocessableEntity: 422 Unprocessable Entity on POST request for "https://api.example.com/resource": [no body] with the default error handler and an empty response body. Read the exception body when present. Message builder, exception subclasses.

Spring 7 adds WebClientResponseException$UnprocessableContent: 422 Unprocessable Content from POST https://api.example.com/resource. Both names identify status 422. Spring source.

What it means

RFC 9110 section 15.5.21 defines 422 as: the server understands the content type and the syntax is correct, but it was unable to process the contained instructions. Typical triggers are a missing required field, a wrong data type, an email that fails a format rule, or a business rule such as an end date before the start date. The name was “Unprocessable Entity” in WebDAV (RFC 4918); RFC 9110 renamed it “Unprocessable Content”. Libraries and older docs still use either phrase.

HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json

{
  "type": "https://example.com/problems/validation-error",
  "title": "Your request parameters didn't validate.",
  "status": 422,
  "errors": [
    { "field": "email", "message": "must be a valid email address" },
    { "field": "age", "message": "must be at least 18" }
  ]
}

What you actually see in each framework

FastAPI (Pydantic v2) answers with a detail array where loc is the path to the bad field:

{
  "detail": [
    { "type": "missing", "loc": ["body", "email"], "msg": "Field required", "input": {} }
  ]
}

Laravel validation produces this JSON shape when the request expects JSON; a traditional form submission redirects back with session errors:

{
  "message": "The email field is required.",
  "errors": { "email": ["The email field is required."] }
}

Rails maps ActionController::InvalidAuthenticityToken (“Can’t verify CSRF token authenticity”) to 422. For form re-renders with errors, controllers choose the status: Turbo displays failed submissions when the response uses a 4xx status such as 422. The GitHub REST API returns 422 with "message": "Validation Failed" and an errors array of resource, field and code. Spring MVC request validation and Django REST framework serializer validation default to 400; inspect their error bodies for the failing fields. Spring mappings, DRF exceptions.

Common causes by stack

  • FastAPI / Pydantic: missing fields or invalid path, query and body values produce 422 with a detail array; loc starts with the input location. Fix the named input, not just the JSON body. FastAPI validation.
  • Laravel: $request->validate(...) throws ValidationException on failure; requests expecting JSON receive 422 with message and errors. Send Accept: application/json for an API workflow and fix the rule named in the error. CSRF token mismatches map to 419. Validation docs, exception handler.
  • Rails: ActionController::InvalidAuthenticityToken maps to 422; restore the CSRF token and matching session cookie. For model validation, the controller chooses the response status; render the failed form with 422 for Turbo. Rails mappings, Turbo form handling.
  • Express: the safeParse handler below explicitly selects 422 for schema errors; fix the reported field path. Express’s JSON parser uses 400 for malformed JSON, so keep parser failures separate from this handler. Express parser errors.

FastAPI also returns 422 for malformed JSON: its router wraps JSONDecodeError in RequestValidationError, with type: "json_invalid" and msg: "JSON decode error". That is a framework convention beyond the RFC’s semantic-validation definition. Fix the JSON syntax before looking for a field rule. FastAPI router source.

Fix it as the client

  1. Read the response body; do not stop at the status line. The field name is in loc, errors or details.
  2. Compare field types to the API schema: "qty": "2" vs 2, dates in ISO 8601 (2027-01-31T10:00:00Z), enums with the exact casing.
  3. Check for required fields you sent as null or an empty string.
  4. For Rails CSRF 422s, send the token in X-CSRF-Token and make sure the session cookie is attached (see cookie not sent).

Reproduce with curl so you can see the raw body:

curl -sv -X POST https://api.example.com/users \
  -H 'Content-Type: application/json' \
  -d '{"email":"not-an-email","age":-5}'

Handling 422 in a workflow

With FastAPI, loc: ["query", "limit"] points to the URL query, while ["body", "items", 0, "quantity"] points to the first item in a JSON array. Laravel uses dotted error keys for nested fields, such as users.0.email. Match these paths to form fields so users can correct the rejected value. Keep the submitted data available while displaying the error; a status-only alert loses the field information the server already supplied. FastAPI errors, Laravel response format.

A workflow retry should use corrected input. For a validation failure, route the error body to the step that collects or transforms the data. For a Rails CSRF failure, refresh the page’s token and session before submitting again. If the response contains json_invalid, validate the serialized bytes instead of changing field values. These are different repairs for the same status number; choose from the response body and the framework that sent it.

Build it as the API author

Return all validation errors at once, in one machine-readable shape. RFC 9457 application/problem+json is the standard container:

// Express with a schema validator such as zod
app.post('/users', (req, res) => {
  const result = userSchema.safeParse(req.body)
  if (!result.success) {
    return res.status(422).type('application/problem+json').json({
      type: 'https://example.com/problems/validation-error',
      title: "Your request parameters didn't validate.",
      status: 422,
      errors: result.error.issues.map((i) => ({ field: i.path.join('.'), message: i.message }))
    })
  }
  res.status(201).json(createUser(result.data))
})

Keep secrets out of error output. Use 409 Conflict when valid data conflicts with current server state; reserve 422 for instructions the API rejects as invalid.

422 versus neighbors

The request builder lets you send an invalid body and inspect the response.

See also the comparison 400 vs 422: which of the two to return for validation errors and what common frameworks default to.

Frequently asked questions

How should a workflow handle a 422 error?

Read and preserve the validation response, map its field paths back to the input step, and resend corrected data. FastAPI uses loc paths and Laravel uses dotted errors keys; for a Rails CSRF failure, restore the token and matching session cookie.

What does 422 Unprocessable Content mean?

The server understood the content type and the body parsed correctly, but the data inside is semantically invalid, for example a missing required field, a malformed email or a negative quantity. It was called "Unprocessable Entity" in WebDAV (RFC 4918) and renamed in RFC 9110; the status number is unchanged.

What is the difference between 422 and 400?

400 means the request could not be parsed or is malformed at the syntax level, such as broken JSON. 422 means the syntax was fine but the values failed validation. Many APIs, including Spring and Django REST framework by default, return 400 for both, so follow whatever your API documents.

Why does FastAPI return 422?

FastAPI validates request data with Pydantic and automatically answers 422 with a detail array that lists each failing field under loc, with a msg and type. Read loc to find the field, for example ["body", "email"], and msg for the reason.

Why do I get 422 Invalid Authenticity Token in Rails?

Rails raises ActionController::InvalidAuthenticityToken, rendered as 422, when a form or fetch request lacks a valid CSRF token. Include the csrf_meta_tags value as an X-CSRF-Token header for AJAX, and confirm the session cookie is being sent.

Should I use 400 or 422 in my own API?

Either is defensible. Use 400 for syntax errors and 422 for validation failures if you want clients to distinguish them, and return the same machine-readable error body for both. Pick one convention and document it.

Sources

  1. MDN Web Docs: 422 Unprocessable Contentdeveloper.mozilla.org
  2. RFC 9110 Section 15.5.21: 422 Unprocessable Contentrfc-editor.org
  3. RFC 9457: Problem Details for HTTP APIsrfc-editor.org
  4. RFC 4918 Section 11.2: original WebDAV definition of 422rfc-editor.org

Keep going

Browse /search