Skip to content

Validation Errors

Validation errors are the most common errors an API returns, and the ones clients most want to render nicely. A good validation response tells the user exactly which fields are wrong and why — all of them at once, not one per round trip.

When the request parsed correctly but the values fail your rules, return 422 Unprocessable Entity. Some teams use 400 for all client errors; either is defensible, but be consistent. Reserve 400 for requests you could not even parse.

Extend Problem Details with an errors array, one entry per offending field:

{
"type": "https://api.example.com/problems/validation",
"title": "Validation failed",
"status": 422,
"detail": "The request has 2 invalid fields.",
"errors": [
{ "field": "email", "message": "must be a valid email address" },
{ "field": "age", "message": "must be 18 or greater" }
]
}

Validate every field and gather all failures before responding — do not bail on the first. This mirrors how a typical schema validator works:

JavaScript

In TypeScript projects a schema library (such as zod) gives you this for free: parse the input against a schema, and on failure map the issues to your errors array.

Advantages (Validation Errors)Trade-offs
Clients know which field is wrong and why — better UXValidation logic ends up duplicated between client and server
Prevents invalid data from reaching the databaseA verbose error response for forms with many fields
A clear 400/422 keeps retry logic correctSome rules need a database query (e.g. email uniqueness)
Machine-readable errors let the client show inline messages

Returning one error at a time for multiple bad fields Symptom:

  • A form has 5 invalid fields, but the API returns errors one field at a time
  • The user fixes the first field, resubmits, sees the second error, fixes it, resubmits again…
  • Validate every field at once and return the full errors array in one response

Mixing validation errors with business rule errors Symptom:

  • 400 Bad Request used for both “invalid email format” and “this email is suspended”
  • The client can’t tell whether to show a field error or a general error
  • Split them: 422 for validation, 409 or a custom code for business rules

💡 Real-world examples

Stripe API:

  • { "error": { "type": "invalid_request_error", "param": "amount", "message": "Amount must be greater than 0" } }
  • param names the field at fault — the client shows an inline error there

GitHub API:

  • { "errors": [{ "resource": "Issue", "field": "title", "code": "missing_field" }, { "resource": "Issue", "field": "body", "code": "missing_field" }] }
  • Returns validation errors for every field at once, not one at a time

Sources: Stripe API — errors, GitHub REST API errors

Input parses fine but two fields break business rules. Best status?
Why return all validation errors at once instead of the first?
What makes a validation error body easy for clients to render?