Introducing Highlights: the context that matters

HTTP 422 Unprocessable Content: What It Means and How to Fix It

HTTP 422 Unprocessable Content is a status code meaning the server understands the request’s content type and the syntax is valid, but it cannot process the instructions inside, such as a JSON body that fails validation. RFC 9110 renamed it from Unprocessable Entity, the name used in the older WebDAV specification.

Code
422
Name
Unprocessable Content
Class
4xx client error
Retry?
No, fix the cause first

What causes a 422 error?

  • →A field with the wrong type, such as a string where a number is expected.
  • →A required field that is missing or empty.
  • →Values that are valid alone but invalid together, such as an end date before the start date.
  • →A schema that changed on the server while the client still sends the old shape.

How do you fix a 422 error when web scraping?

  • →Read the error body. Most frameworks list each invalid field and the rule it broke.
  • →Validate payloads on the client with the same schema the API publishes, for example an OpenAPI spec.
  • →Do not retry unchanged. Fix the data, then resend.

How do you fix a 422 error on your own server?

  • →Return field-level errors with a path and a message for each failure.
  • →Keep 400 for requests that cannot be parsed and 422 for requests that parse but fail validation, and document the choice.

How do you handle a 422 error in a retry loop?

422 is not in RETRYABLE, so raise_for_status() raises on the first response instead of spending retries on a request that will fail the same way. Fix the cause, then send the request again.

import random
import time

import requests

RETRYABLE = {408, 429, 500, 502, 503, 504, 520, 521, 522, 523, 524}


def fetch(url: str, max_attempts: int = 5) -> requests.Response:
    for attempt in range(max_attempts):
        try:
            response = requests.get(url, timeout=(10, 60))
        except requests.Timeout:
            time.sleep(2**attempt + random.uniform(0, 1))
            continue
        if response.status_code not in RETRYABLE:
            response.raise_for_status()
            return response
        retry_after = response.headers.get("Retry-After", "")
        backoff = 2**attempt + random.uniform(0, 1)
        time.sleep(min(int(retry_after) if retry_after.isdigit() else backoff, 60))
    raise RuntimeError(f"Gave up on {url} after {max_attempts} attempts")

How does Context.dev handle a 422 error?

The Context.dev API answers invalid options with 400 and a message that names the problem rather than 422. The OpenAPI spec lists every parameter so you can validate requests before you send them.

See what the web scraping API does on every request, or read how to fix HTTP errors in web scraping for a longer walkthrough.

Frequently asked questions about a 422 error

What is the difference between 400 and 422?

A 400 means the server could not parse or accept the request. A 422 means it parsed it, but the content broke a validation rule.

Is 422 Unprocessable Entity the same as Unprocessable Content?

Yes. Same code, same meaning. RFC 9110 adopted the code for general HTTP use and renamed it from the WebDAV-era "Unprocessable Entity".

Should I retry a 422?

No. The content is invalid and will fail the same way until you change it.

Which status codes are related to 422?

Sources

Last reviewed

Ship an agent that actually knows things.

Free tier, 10-minute integration, and the same API powering agents at Mintlify, daily.dev, and Propane. No credit card to start.