HTTP 422 Unprocessable Entity

The server understands the content type and syntax of your request, but the data itself is semantically invalid. For example, the JSON is valid but contains a negative age value or an email field with a phone number. The request is well-formed but logically wrong.

What Is HTTP 422 Unprocessable Entity?

HTTP 422 Unprocessable Entity is a client error status code from the WebDAV extension to HTTP, now widely adopted in modern API design. It indicates that the server understands the content type of the request body and the syntax is correct, but the semantic content is invalid. In simpler terms, the JSON or XML is well-formed, but the values it contains do not make logical sense or violate validation rules.

The distinction between 400 Bad Request and 422 Unprocessable Entity is important for API design. A 400 error means the request cannot be parsed at all, such as malformed JSON with missing brackets or an invalid Content-Type header. A 422 error means the request was successfully parsed but the data failed semantic validation, such as a negative age value, an end date before a start date, or a required field containing an empty string. This distinction helps API consumers understand whether the problem is in the request format or the request content.

Many modern API frameworks have adopted 422 as the standard response for validation failures. Ruby on Rails, Laravel, FastAPI, and Django REST Framework all use 422 by default when model validation fails. However, some APIs, particularly those following strict HTTP/1.1 conventions, use 400 for all client-side validation errors. Neither approach is wrong, but consistency within an API is essential for a good developer experience.

Common Causes

Failed Validation Rules

The request body passes syntax checks but fails business validation. For example, an age field with a value of -5, a date in the past for a future event, or a password that does not meet complexity requirements.

Invalid Field Relationships

Individual fields are valid but their combination is not. For example, an end date that is before the start date, or a shipping address in a country that the service does not deliver to.

Semantic Type Mismatch

A field contains the wrong type of valid data. For example, an email field containing a phone number, a URL field containing an IP address, or a currency amount with too many decimal places.

Business Rule Violation

The data violates a business constraint, such as ordering a quantity greater than available inventory, setting a price below the minimum allowed, or scheduling an appointment outside business hours.

How to Fix

Read Validation Error Details

The 422 response body should list which fields failed validation and why. Use these details to fix the specific fields that are semantically invalid.

Validate Client-Side First

Implement the same validation rules in your frontend to catch errors before sending the request. This provides instant feedback and reduces unnecessary server round trips.

Check Field Formats

Ensure emails are in email format, URLs are valid URLs, dates are in the expected format, and numbers are within acceptable ranges. Match the API's expected formats exactly.

Distinguish from 400

Use 422 for semantically invalid data in a syntactically correct request. Use 400 for requests that cannot be parsed at all due to malformed syntax.

Code Examples

Express.js

// Express.js — 422 for semantic validation errors
const express = require('express');
const app = express();
app.use(express.json());

app.post('/api/events', (req, res) => {
  const { title, startDate, endDate, maxAttendees } = req.body;
  const errors = {};

  // Semantic validation (syntax is fine, logic is not)
  const start = new Date(startDate);
  const end = new Date(endDate);

  if (start < new Date()) {
    errors.startDate = 'Start date must be in the future';
  }
  if (end <= start) {
    errors.endDate = 'End date must be after start date';
  }
  if (maxAttendees !== undefined && maxAttendees < 1) {
    errors.maxAttendees = 'Must allow at least 1 attendee';
  }
  if (title && title.length > 200) {
    errors.title = 'Title cannot exceed 200 characters';
  }

  if (Object.keys(errors).length > 0) {
    return res.status(422).json({
      error: 'Unprocessable Entity',
      message: 'Validation failed',
      fields: errors
    });
  }

  // ... create event
  res.status(201).json({ id: 1, title, startDate, endDate });
});

Flask (Python)

# Flask — 422 for semantic validation errors
from flask import Flask, jsonify, request
from datetime import datetime

app = Flask(__name__)

@app.route('/api/events', methods=['POST'])
def create_event():
    data = request.get_json()
    errors = {}

    # Semantic validation
    try:
        start = datetime.fromisoformat(data.get('start_date', ''))
        if start < datetime.now():
            errors['start_date'] = 'Start date must be in the future'
    except ValueError:
        errors['start_date'] = 'Invalid date format'

    try:
        end = datetime.fromisoformat(data.get('end_date', ''))
        if 'start_date' not in errors and end <= start:
            errors['end_date'] = 'End date must be after start date'
    except ValueError:
        errors['end_date'] = 'Invalid date format'

    max_att = data.get('max_attendees')
    if max_att is not None and max_att < 1:
        errors['max_attendees'] = 'Must allow at least 1 attendee'

    if errors:
        return jsonify(
            error='Unprocessable Entity',
            message='Validation failed',
            fields=errors
        ), 422

    # ... create event
    return jsonify(id=1, title=data['title']), 201

Frequently Asked Questions

What is the difference between 422 and 400?

HTTP 400 means the request is syntactically invalid and cannot be parsed at all, such as malformed JSON. HTTP 422 means the syntax is correct but the content is semantically invalid, such as an email field containing a phone number. Use 400 for parse errors and 422 for validation errors.

Is 422 part of the standard HTTP specification?

HTTP 422 was originally defined in RFC 4918 as part of the WebDAV extension. While not in the original HTTP/1.1 spec, it has been widely adopted by modern APIs and frameworks. RFC 9110 (2022) includes it in the updated HTTP semantics specification.

Should I use 422 or 400 for validation errors?

Both approaches are valid. Use 422 if you want to distinguish between parse errors (400) and validation errors (422). Use 400 for all client errors if you prefer simplicity. The most important thing is consistency across your API.

How should I structure a 422 error response?

Include a top-level error message and a fields or errors object mapping each invalid field to its specific error message. This structure allows clients to display inline validation errors next to the corresponding form fields.

Do frameworks use 422 by default?

Yes, many modern frameworks return 422 for validation failures. Ruby on Rails, Laravel, FastAPI, and Django REST Framework all use 422 by default. Express.js and Flask leave the choice to the developer.

Monitor Your APIs & Services

Get instant alerts when your endpoints go down. 60-second checks, free forever.

Start Monitoring Free →