Resource library

QA How-To

HTTP 400 vs 422: What Testers Need to Know

Understand HTTP status 400 vs 422 for malformed and semantically invalid requests, with API test matrices, automation, error schemas, and interview answers.

25 min read | 3,920 words

TL;DR

HTTP 400 is a general bad-request response, often used when malformed syntax or basic request structure blocks processing. HTTP 422 means the content type and syntax were understood, but the instructions could not be processed. Testers should follow the documented API convention, exercise each validation layer, validate the error representation, and prove rejected requests caused no state change.

Key Takeaways

  • 400 Bad Request is a broad client-error response commonly used when request syntax, framing, or basic structure prevents processing.
  • 422 Unprocessable Content means the server understands the content type and syntax but cannot process the contained instructions.
  • An API can consistently use 400 for validation failures, so test the published contract rather than imposing a universal framework convention.
  • Build test cases by validation layer: transport, media type, parsing, schema, cross-field, current state, authorization, and dependency behavior.
  • Verify a stable machine-readable error schema, field paths, safe messages, correlation metadata, and zero unintended state change.
  • Test precedence with requests that violate multiple rules so authentication, parsing, validation, and conflict responses do not leak data or vary unpredictably.
  • Use boundary, property-based, contract, and mutation-focused tests to cover validation behavior without creating an unmaintainable Cartesian product.

The http status 400 vs 422 distinction separates two kinds of client failure, but real APIs do not all draw the line in the same place. 400 Bad Request is a broad response for a request the server cannot or will not process because the request is considered a client error. 422 Unprocessable Content is more specific: the server understands the content type and the content syntax, but cannot process the instructions.

For testers, the goal is not to enforce a favorite status convention. The goal is to make the API's chosen boundary explicit, consistent, safe, and useful to clients. That requires malformed payloads, schema violations, domain rules, multi-error precedence, state checks, and a stable error representation. This guide shows how to build that coverage without a brittle negative-test explosion.

TL;DR

Request condition Common status Why
Truncated or malformed JSON 400 JSON syntax cannot be parsed
Valid JSON with missing required field 422 in APIs that separate semantic validation, otherwise documented 400 Syntax is valid, instructions fail input rules
Correct fields with an impossible date range 422 or documented 400 Cross-field semantic rule fails
Unsupported Content-Type 415 Media type is not accepted
Resource state conflicts with a valid command 409 is often more expressive Request conflicts with current state
Missing authentication 401 Credentials are absent or invalid
Authenticated caller lacks permission 403 Authorization fails

Status selection is only one part of the oracle. Also validate the problem code, field location, safe detail, correlation information, headers, and unchanged business state.

1. HTTP Status 400 vs 422 in Protocol Terms

400 Bad Request means the server cannot or will not process the request because of something perceived as a client error. The category is intentionally broad. Malformed request syntax, invalid framing, and deceptive request routing are examples, but the definition is not limited to JSON parse failures. An API can choose 400 for validation errors and remain coherent if that convention is documented and consistently implemented.

422 Unprocessable Content means the server understands the content type and the content syntax is correct, but it cannot process the contained instructions. The current reason phrase is Unprocessable Content. Many frameworks, articles, and legacy contracts still say Unprocessable Entity because the status originated in WebDAV under that name. Tests should assert the numeric code and documented representation, not depend on a reason phrase that protocols or clients may omit.

Consider Content-Type: application/json with a missing closing brace. The server recognizes JSON but cannot parse the JSON syntax, so 400 is a clear result. Now consider valid JSON containing startDate later than endDate. The syntax is correct and the instruction is understood, but the domain rule fails, so 422 is expressive in an API that uses semantic-validation separation.

The boundary can be fuzzy. A missing required property is a schema violation, but the JSON syntax remains valid. Some teams classify it as 422, while others treat the complete request grammar as invalid and use 400. QA should ask for one public contract, then test consistency across endpoints, versions, gateways, and generated clients.

2. Map the Validation Pipeline Before Choosing Assertions

Model request handling as ordered layers. A typical pipeline includes connection and HTTP parsing, routing, content negotiation, authentication, authorization, content decoding, schema validation, cross-field rules, resource lookup, current-state conflict checks, persistence, and downstream work. Actual order varies, and security can require authentication before detailed validation.

Layer Example defect Typical response candidate State oracle
HTTP parsing Invalid header or framing 400, often handled by edge server No application invocation
Media type text/plain sent to JSON-only endpoint 415 No domain mutation
JSON parsing Trailing token or truncated object 400 No validator or mutation
Shape validation Required property absent 422 or contractually 400 No domain mutation
Field rule Quantity is zero 422 or contractually 400 No domain mutation
Cross-field rule End precedes start 422 or contractually 400 No domain mutation
Current state Version is stale or item already closed 409 or 412 as designed Existing state unchanged
Authorization Caller cannot modify account 403, sometimes concealment with 404 No disclosure or mutation

This map prevents one assertion from absorbing unrelated failures. If malformed JSON receives 415 because Content-Type is wrong, the test did not reach the parser. If a forbidden caller receives detailed field errors, validation order may expose business rules or resource shape. If a valid instruction conflicts with current state, 409 can be clearer than 422 because the content could succeed under a different state.

Document the chosen order. Then create one focused test per layer plus deliberate multi-fault cases for precedence. The response should be deterministic enough that clients know what to fix first.

3. Distinguish Malformed Syntax from Invalid Meaning

Malformed input cannot be parsed into the representation the endpoint expects. JSON cases include a missing delimiter, invalid string escape, extra trailing token, or unquoted property name. Send raw bytes for these tests. A high-level client option such as json=payload always serializes valid JSON and cannot exercise parser failure. Set Content-Type explicitly and pass the malformed content string.

Semantically invalid input parses successfully. Examples include a syntactically valid email string that violates product policy, a negative quantity, an unsupported enum value, duplicate array members when uniqueness is required, a date outside the allowed window, or two fields that cannot appear together. Missing required properties also belong in this group for contracts that use 422 for representation validation.

Differentiate invalid type from invalid value. quantity: 'five' might fail schema typing, while quantity: 0 might pass integer typing and fail a minimum constraint. Test null, omission, empty string, whitespace, zero, negative, fractional, maximum, just-over-maximum, Unicode, normalization, and duplicated values only where relevant to the field. Do not copy a generic list onto every input.

Also separate client-invalid content from server failure. If a valid enum causes an unhandled database exception, the response should not be relabeled 422 simply because the error occurred during processing. A 5xx response, safe error body, rollback, and alerting may be appropriate. Tests should prevent broad exception handlers from turning internal defects into misleading client blame.

Use boundary value analysis with examples to choose high-yield values around each documented constraint.

4. Decide When 409, 412, 415, or 401 Is More Precise

400 and 422 are not the whole negative-response vocabulary. 415 Unsupported Media Type fits a request whose Content-Type is not supported. If an endpoint requires JSON and receives XML, the server has not accepted the content type, so the precondition for 422 is absent. Test missing Content-Type separately because some APIs infer JSON while others require an explicit header.

409 Conflict often fits a valid instruction that cannot complete because of current resource state. Creating a username that already exists, transitioning a shipped order back to draft, or modifying a locked record can be modeled as conflict. A team can still include some domain conflicts under 422, but clients benefit from a documented, consistent distinction between invalid instruction and state-dependent conflict.

412 Precondition Failed is appropriate when a conditional request header such as If-Match evaluates false. That is more precise than a field-validation error. Test the current ETag success path and stale ETag failure path. The rejected request must leave the newer version untouched.

401 Unauthorized handles absent or invalid authentication credentials. 403 Forbidden handles an authenticated principal without permission. Authentication and authorization commonly run before detailed validation to prevent resource or schema leakage. A malformed body sent without credentials may therefore receive 401 rather than 400. Your multi-fault test should enforce the security design, not demand parser-first behavior.

Rate limits, oversized payloads, and URI length have other candidates such as 429, 413, and 414. An API that returns 400 for every client-visible problem may be simple but less actionable. QA can report inconsistency and consumer impact while respecting deliberate compatibility decisions.

5. Build Runnable pytest and Requests Tests

The Requests library lets a test send either serialized JSON through json= or deliberately malformed raw content through data=. Install pytest and requests, configure an approved test endpoint, and run pytest -q. The sample contract uses 400 for JSON parsing and 422 for valid JSON that violates field rules.

# test_booking_validation.py
import os
from urllib.parse import urlparse

import pytest
import requests

BASE_URL = os.getenv('API_BASE_URL', 'http://127.0.0.1:8080')
TOKEN = os.getenv('API_TOKEN', 'local-test-token')
ALLOWED_HOSTS = {'127.0.0.1', 'localhost', 'api.test.example'}

if urlparse(BASE_URL).hostname not in ALLOWED_HOSTS:
    raise RuntimeError('Refusing to run negative tests on an unapproved host')

@pytest.fixture
def session():
    client = requests.Session()
    client.headers.update({
        'Authorization': f'Bearer {TOKEN}',
        'Accept': 'application/problem+json',
    })
    yield client
    client.close()

def test_malformed_json_returns_400(session):
    response = session.post(
        f'{BASE_URL}/v1/bookings',
        headers={'Content-Type': 'application/json'},
        data='{"startDate": "2026-08-20",',
        timeout=10,
    )

    assert response.status_code == 400
    assert response.headers['content-type'].startswith('application/problem+json')
    problem = response.json()
    assert problem['status'] == 400
    assert problem['code'] == 'malformed_json'

def test_valid_json_with_invalid_range_returns_422(session):
    response = session.post(
        f'{BASE_URL}/v1/bookings',
        json={'startDate': '2026-08-20', 'endDate': '2026-08-10'},
        timeout=10,
    )

    assert response.status_code == 422
    problem = response.json()
    assert problem['status'] == 422
    assert problem['code'] == 'validation_failed'
    assert any(error['path'] == '/endDate' for error in problem['errors'])

requests.Session, headers.update, post, status_code, headers, and json are current public APIs. The JSON field names and problem codes are example contract details, not universal standards. Adapt them to the service specification. Keep malformed strings small so test reports remain readable.

Never send parser-fuzzing volume to production. Run bounded cases against an authorized environment, and sanitize response details before attaching them to shared reports.

6. Validate the Error Representation as a Product Contract

A useful error body lets a human and client identify the problem without exposing internals. A common design uses application/problem+json with fields such as type, title, status, detail, and instance, plus documented extensions like a stable machine code and field-error array. The exact shape is a product decision. Validate it with the same rigor as a success representation.

Assert that body status agrees with HTTP status. Machine codes should be stable, documented, and suitable for branching. Human detail can evolve or be localized, so avoid exact full-sentence assertions unless wording itself is a requirement. Field paths should use one documented notation, such as JSON Pointer, and identify array indices predictably. A client should not have to parse English to locate items[2].quantity.

Test one error and multiple errors. Does the server return all independent field failures, only the first, or a bounded set? Is ordering deterministic? Are cross-field errors attached to one field, the document root, or both? Consumers need these rules for accessible form feedback. Protect against response amplification by capping errors for huge arrays or repeated invalid fields.

Error detail must not contain stack traces, SQL fragments, class names, internal hostnames, secrets, full tokens, or another tenant's data. A correlation or instance identifier can help support find the server log without exposing implementation. Verify it uses an approved format and cannot be controlled to inject logs.

Contract-test the error schemas in OpenAPI. Separate 400, 422, 409, and other representations where their fields differ. For a deeper strategy, see API error handling and negative testing.

7. Prove Rejected Requests Cause No State Change

A correct client-error response is atomic from the business perspective. The request should not create a booking, decrement inventory, reserve capacity, emit a customer notification, or enqueue work before validation rejects it. Check an authoritative state surface using a unique client reference. For high-risk domains, inspect controlled downstream ledgers or event sinks too.

Validation order can produce partial work. A loop might save valid line items before reaching an invalid item. A file import might enqueue work before validating metadata. A service might emit an audit event that incorrectly claims success. Create a payload where a later nested element fails, then verify the entire atomicity policy. If partial success is intended, a single 422 for the entire operation may be misleading. The response needs per-item outcomes and a documented transaction model.

Capture before and after counts only in isolated tests. Shared environments make global counts flaky. Prefer unique business identifiers, tenant isolation, or a test-only controlled repository. Poll only when the architecture is asynchronous, using a deadline and stable identifier. A quick absent result followed by later accidental creation is a defect that immediate assertions can miss.

Retry the corrected request. A validation failure should not normally consume an idempotency key in a way that blocks a fixed payload, unless the contract explicitly binds and records all attempts. Test the documented rule. Also verify rate-limit accounting and audit behavior are not bypassable through invalid requests. Rejection may still be recorded for security, but it must not masquerade as a successful business action.

8. Test Multiple Violations, Precedence, and Determinism

Real bad requests often violate more than one rule. A request can have an expired token, wrong Content-Type, malformed JSON, and a forbidden target. The service must choose a response without leaking protected information or varying unpredictably across instances. Create a small precedence table with security and platform owners.

Common safe expectations include rejecting unauthenticated callers before detailed resource validation and handling malformed HTTP at the edge before application authentication. But there is no universal pipeline. A gateway may validate tokens before routing, while a service parses a path before body decoding. Test the deployed path, including gateway transformations, not only a controller unit.

Within a valid JSON document, send two independent invalid fields and one cross-field violation. Confirm whether the API returns a bounded collection or a deterministic first failure. Repeat object-member order to ensure the machine result does not depend on JSON property order unless sequential processing is explicitly part of the contract. Reorder array elements only when array order is not semantically meaningful.

Concurrency can change current-state results. Two individually valid reservation requests may race, with one succeeding and one returning 409 rather than 422. A stale read should not make the service claim that a value was intrinsically invalid. Use deterministic barriers or component-level control to exercise the state transition.

Stable precedence makes clients simpler and security reviews stronger. It also keeps monitoring meaningful. If the same malformed request becomes 400 at one instance and 422 at another, investigate configuration drift, schema versions, or middleware order.

9. Apply Boundary, Equivalence, and Property-Based Design

Validation testing can become a Cartesian product. Use equivalence partitions to choose representatives: omitted, null, wrong type, valid lower boundary, valid typical value, valid upper boundary, and just-outside values. Add format-specific partitions only when they exercise different parser or domain behavior. For a date, invalid calendar syntax and valid but prohibited date are distinct.

Boundary analysis is especially useful for length, numeric range, array size, precision, time window, and pagination constraints. Verify the documented unit. A name limit can count bytes, Unicode code points, or grapheme clusters. A currency amount can use integer minor units or decimal rules. A timestamp boundary can depend on UTC, tenant timezone, or an inclusive comparison. Do not invent the expectation from a database column.

Property-based testing can generate valid structures and mutate one rule at a time. Preserve a reproducible seed and shrink failures to a minimal case. Constrain generators so they do not produce dangerous volume, deeply nested denial-of-service payloads, or accidental secrets. Pair generated coverage with readable named examples for business-critical rules.

Metamorphic relationships add strong oracles. Reordering JSON object members should not change validation. Normalizing an allowed email case may or may not change identity according to policy. Adding an unknown field should be rejected or ignored consistently. Replacing one valid item with one invalid item should produce a path pointing at that item and no partial creation.

Track rules to tests through schema or requirement IDs. Coverage is about behavior boundaries, not the number of invalid values.

10. Design the HTTP Status 400 vs 422 Test Matrix

A reusable endpoint matrix can include:

  1. Malformed HTTP or invalid header syntax -> edge-defined 400, no application work.
  2. Unsupported media type -> 415.
  3. Malformed JSON with correct media type -> 400.
  4. Valid empty JSON object -> 422 or documented 400 for missing fields.
  5. Wrong JSON top-level type -> documented schema-validation status.
  6. Missing, null, wrong-type, and out-of-range fields -> stable field paths and codes.
  7. Cross-field violation -> document-level or field-level semantic error.
  8. Unknown property -> reject or ignore according to schema policy.
  9. Valid instruction conflicting with current state -> documented 409 or 422 policy.
  10. Missing or invalid credentials plus invalid body -> secure precedence.
  11. Forbidden principal plus valid and invalid bodies -> no protected detail leak.
  12. Valid request that triggers dependency failure -> 5xx, rollback, no client blame.
  13. Corrected retry -> success without poisoned idempotency state.
  14. Large invalid array -> bounded error response and safe processing.
  15. Localized client -> stable codes and paths regardless of message language.

For each row, capture status, media type, schema, machine code, field path, safe detail, correlation metadata, headers, authoritative state, side effects, and relevant logs. Run a small deterministic set in pull requests. Put expensive property, concurrency, gateway, and abuse-resistance checks in appropriate scheduled jobs.

Do not create assertions that merely restate framework defaults. Tie every expected code to the public API contract. If a framework upgrade changes missing-field responses from 400 to 422, exact tests should fail so the team makes a compatibility decision rather than shipping silently.

11. Review Security, Privacy, and Abuse Resistance

Validation is part of the attack surface. Deep nesting, oversized strings, huge arrays, expensive regular expressions, decompression, and ambiguous encodings can consume resources before the request is rejected. Enforce size and time limits at suitable layers, then test just below and just above approved boundaries. Coordinate load and abuse tests, and never direct them at production without explicit authorization.

Mass assignment is another risk. Send protected fields such as role, approved, ownerId, price, or createdBy. The server should reject or safely ignore them according to its unknown-property policy, and authoritative state must retain server ownership. A 422 response is useless if the privileged field was already applied.

Error messages can become enumeration oracles. A registration API that distinguishes an existing email from a new one may expose account membership. Authentication and password-reset flows often need intentionally generic public detail while recording precise internal codes. Test timing and response shape only within approved security scope, and avoid claims of constant time without controlled measurement.

Unicode normalization, duplicate JSON property names, numeric overflow, exponent notation, and content-type parameter variations deserve parser-specific review. Different gateways and languages can interpret the same bytes differently. Reject ambiguous input consistently before signatures, authorization, and business rules disagree.

Use API security testing basics to expand these cases into an authorized threat model. Validation quality is not just usability. It protects state integrity, resource capacity, and privacy.

12. Make Error Responses Useful to UIs and SDKs

A web form needs to map field errors to controls, announce a summary, preserve safe input, and focus the first relevant problem. Stable paths and codes matter more than a developer-friendly stack trace. Test that the UI handles 400 document errors separately from 422 field errors when the contract distinguishes them. A malformed client-generated JSON request is often an application defect, not something an end user can fix.

Generated SDKs need every documented status and schema. If OpenAPI lists only 400 but the provider emits 422, an SDK may throw a generic exception and discard the field array. Contract tests should make undocumented responses visible. Client code should still retain the raw status and safe body for diagnostics, subject to privacy controls.

Localization should affect human text, not machine codes, field paths, or status. Test two locales if the server localizes messages. Ensure unsupported locale negotiation does not hide the original validation problem under another error. UI tests should assert accessible association and code-driven behavior, not a full translated sentence unless translation accuracy is in scope.

Analytics can track bounded machine codes and endpoint templates. Do not use raw invalid values, email addresses, resource IDs, or free-form detail as metric labels. Logs can include a safe correlation ID and internal reason under access control. Redact request bodies by classification, even when they are invalid.

A good error contract helps a client recover, helps support correlate, and helps QA diagnose without exposing implementation. That is more valuable than winning a debate over one numeric code.

Interview Questions and Answers

Q: What is the difference between HTTP 400 and 422?

400 is a broad client-error response, commonly used when malformed syntax or basic request problems prevent processing. 422 means the content type and syntax were understood, but the contained instructions could not be processed. I follow the API's documented classification for schema and business validation.

Q: Is 422 only for WebDAV?

No. The status originated in WebDAV, but HTTP semantics now define 422 Unprocessable Content for general use. Older material often calls it Unprocessable Entity. Tests should focus on code and contract rather than reason-phrase wording.

Q: Should a missing required JSON field return 400 or 422?

Both conventions exist. An API that separates parse errors from semantic validation often uses 422, while another can consistently classify the whole invalid request as 400. I require clear documentation and consistency across endpoints and clients.

Q: How do you send malformed JSON in automation?

I send raw content with an application/json Content-Type instead of using a client's JSON serializer. A serializer would fix syntax automatically. I keep the malformed case minimal and verify 400, safe error shape, and no state change.

Q: When would you expect 409 instead of 422?

I expect 409 when a valid instruction cannot complete because of current resource state, such as an already-used unique value or prohibited workflow transition. It distinguishes state conflict from an intrinsically invalid representation. The published API model remains authoritative.

Q: What else do you assert besides the status?

I assert media type, problem schema, body status, stable machine code, field path, bounded safe detail, correlation metadata, and relevant headers. I then prove no durable state or downstream side effect changed.

Q: How do you test a request with multiple errors?

I establish precedence across authentication, media type, parsing, validation, and conflict layers. Within validation, I confirm whether the API returns the first error or a bounded deterministic list. Reordering irrelevant JSON members should not change the result.

Q: How do you prevent too many negative tests?

I model validation layers, then use equivalence partitions and boundary values per rule. Property-based mutation covers combinations with reproducible seeds, while named cases protect critical business behavior. I avoid a full Cartesian product with no added risk coverage.

Common Mistakes

  • Claiming 400 is only for malformed JSON or that every validation failure must be 422.
  • Depending on the reason phrase Unprocessable Entity or Unprocessable Content instead of the numeric contract.
  • Using json= in a client and believing the test sent malformed JSON.
  • Returning 422 for an unsupported media type that should be handled as 415 under the API contract.
  • Treating current-state conflict, stale precondition, authentication, and authorization as generic validation.
  • Checking status and message while ignoring partial persistence and downstream side effects.
  • Asserting full human sentences that change with localization or copy edits.
  • Exposing stack traces, SQL, internal field names, account existence, or secrets in error detail.
  • Letting endpoint middleware return inconsistent error shapes and precedence.
  • Generating a massive invalid-input Cartesian product instead of risk-based boundaries and partitions.

Conclusion

The http status 400 vs 422 distinction is most useful when it reflects a stable validation boundary. Use 400 for the API's general bad-request or parse-failure category. Use 422 when the API deliberately communicates that syntax was understood but the instructions failed schema or semantic processing. Choose one documented convention and keep it consistent.

Select one mutation endpoint and draw its validation pipeline. Add one test each for media type, malformed syntax, field rule, cross-field rule, state conflict, and secure precedence. For every rejected request, assert the error contract and unchanged state. That creates far more confidence than a long list of status-only negatives.

Interview Questions and Answers

How do you explain 400 vs 422 in an interview?

400 is a broad bad-request response, commonly used when parsing or basic request structure fails. 422 says the content type and syntax were understood, but the contained instructions could not be processed. I follow and test the API's explicit validation convention.

Would you always use 422 for validation?

No. Many stable APIs use 400 for all validation errors. I evaluate consistency, OpenAPI documentation, client handling, and semantic clarity rather than imposing a framework default. A change between them can be a breaking contract change.

How do you test a malformed JSON request?

I send raw malformed content with the correct application/json media type. I assert 400 and a safe parse-error representation, then verify the request caused no persistence or side effects. Using a JSON serializer would invalidate the test setup.

What is a semantic validation failure?

It occurs when the representation parses but its instructions violate a rule, such as an end date before a start date or quantity below the allowed minimum. An API can report 422 or its documented 400 convention. Field paths and stable codes should identify recovery.

Why test error precedence?

A request can be unauthenticated, malformed, and forbidden at once. Stable precedence prevents inconsistent client behavior and avoids leaking schema or resource details. I test combinations at the deployed gateway and service boundary.

How do you verify no side effects on 400 or 422?

I query authoritative state with a unique client reference and inspect controlled downstream ledgers for critical operations. I include failures late in nested validation to catch partial writes. Corrected retries must remain possible according to idempotency policy.

What belongs in an API problem response?

I expect the documented media type, HTTP-aligned status, stable machine code, safe detail, correlation reference, and predictable field errors. Messages can be localized, so clients should not parse prose. Sensitive implementation and customer data must be excluded.

How would you reduce a large validation test suite?

I map validation layers, group inputs into equivalence partitions, and select boundaries around each constraint. Property-based tests mutate one rule with reproducible seeds. I retain named examples for high-risk business and security rules.

Frequently Asked Questions

What is the difference between HTTP 400 and 422?

400 Bad Request is a broad client-error response, often used for malformed syntax or basic request problems. 422 Unprocessable Content means the media type and content syntax were understood, but the server could not process the instructions. API conventions differ for schema validation.

Should invalid JSON return 400 or 422?

Malformed JSON normally fits 400 because its syntax cannot be parsed. Valid JSON that violates schema or domain rules can use 422 in APIs that make that distinction. The published contract should define the boundary.

What does 422 Unprocessable Entity mean?

Unprocessable Entity is the older reason phrase associated with status 422. Current HTTP semantics call it Unprocessable Content. The numeric status is what clients rely on, and the API should document its error representation.

Can missing required fields return 400?

Yes. Some APIs consistently use 400 for all client input validation, including missing fields. Others use 422 because the JSON syntax is valid but the representation fails processing. Consistency and client compatibility matter more than framework preference.

When should an API return 409 instead of 422?

409 is often useful when a valid instruction conflicts with current resource state, such as a duplicate unique value or invalid workflow transition. 422 is more focused on instructions the server cannot process as submitted. Follow the service's documented model.

How do I test malformed JSON?

Send raw bytes or a raw string with Content-Type application/json. Do not use the client's JSON serialization option because it creates valid JSON. Assert the parse-error response and verify no domain work occurred.

What should an API validation error body include?

It should provide a documented media type, stable machine code, safe human detail, and predictable field paths or error entries. Correlation metadata can help support, while stack traces, secrets, SQL, and other tenants' data must remain hidden.

Related Guides