JSON Schema Validation: Common Errors and How to Fix Them

JSON Schema validation is one of those tools that saves you hours of debugging — until it produces an error message that makes no sense.

I've seen teams spend entire afternoons chasing a validation error that turned out to be a single wrong character. The error messages in most JSON Schema validators are technically correct but not always helpful. Here's a field guide to the most common validation failures, what they actually mean, and how to fix them.

Setup: Our Sample Schema and Data

We'll use this schema throughout:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/user.schema.json",
  "title": "User",
  "type": "object",
  "properties": {
    "id": {
      "type": "integer",
      "minimum": 1
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "role": {
      "type": "string",
      "enum": ["admin", "user", "moderator"]
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "uniqueItems": true
    },
    "address": {
      "type": "object",
      "properties": {
        "city": { "type": "string" },
        "zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" }
      },
      "required": ["city"]
    }
  },
  "required": ["id", "name", "email", "role"],
  "additionalProperties": false
}

Error 1: Type Mismatch

This is the most common validation error. You pass a number where a string is expected, a string where a boolean is expected, or (most frequently) a string where a number is expected.

Bad Input

{
  "id": "abc",
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

Error Message

Validation Error: /id: expected integer, got string

Why It Happens

APIs that accept JSON from form submissions or query parameters often receive all values as strings. The number 42 arrives as the string "42". JSON Schema treats these differently — 42 is an integer, "42" is a string.

Fix

{
  "id": 42,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

Or, if you genuinely might receive string IDs, change the schema:

"id": {
  "type": ["integer", "string"],
  "minimum": 1
}

The type keyword accepts an array of allowed types. This is useful for schemas that must handle loosely-typed API consumers.

Error 2: Missing Required Field

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com"
}

Error Message

Validation Error: /: required property 'role' not found

Why It Happens

The required array in the schema lists ["id", "name", "email", "role"]. If any of those keys is missing, validation fails regardless of whether the other keys are valid.

Fix

Add the missing field:

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

Or, if the field genuinely is sometimes absent, remove it from required:

"required": ["id", "name", "email"]

Debugging Tip

Count the keys in your JSON. If a key is present but its value is null, that's different from the key being absent. required checks for key existence, not value validity. A null value passes required but might fail the property's type constraint.

Error 3: Minimum/Maximum Constraint Violation

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "age": 200
}

Error Message

Validation Error: /age: value 200 exceeds maximum of 150

Why It Happens

The age field has "maximum": 150. Any value above that fails. This seems obvious, but in practice, this error often comes from:

  • A field that was repurposed (a "count" field with a max meant for "age")
  • A client sending values in a different unit (months instead of years)
  • An off-by-one bug in input validation

Fix

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "age": 30
}

Or adjust the schema if the constraint was wrong:

"age": {
  "type": "integer",
  "minimum": 0,
  "maximum": 200
}

Error 4: String Length Violation

Bad Input

{
  "id": 1,
  "name": "",
  "email": "alice@example.com",
  "role": "admin"
}

Error Message

Validation Error: /name: minimum length is 1, got 0

Why It Happens

The name field has "minLength": 1. An empty string fails. This is common when:

  • You generate JSON from template code and the template variable is null/empty
  • A form submits with an empty field that should have been required
  • Data migration imports empty strings from legacy systems

Fix

Don't send empty strings for fields with minLength constraints. Or change the schema to allow empty strings:

"name": {
  "type": "string",
  "minLength": 0,
  "maxLength": 100
}

But usually the right fix is client-side validation that prevents empty submissions.

Error 5: Enum Constraint Violation

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "superadmin"
}

Error Message

Validation Error: /role: "superadmin" is not a valid enum value (must be one of "admin", "user", "moderator")

Why It Happens

The enum keyword restricts values to an explicit list. Any value outside that list fails. This catches:

  • Typos ("admn" instead of "admin")
  • Deprecated values that were removed from the list
  • Values from a newer version of the API being sent to an older schema

Fix

Use one of the allowed values:

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

Or add the new value to the schema if it was an oversight:

"role": {
  "type": "string",
  "enum": ["admin", "user", "moderator", "superadmin"]
}

Error 6: Pattern (Regex) Mismatch

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "address": {
    "city": "San Francisco",
    "zip": "abc"
  }
}

Error Message

Validation Error: /address/zip: string "abc" does not match pattern ^\d{5}(-\d{4})?$

Why It Happens

The zip field has "pattern": "^\\d{5}(-\\d{4})?$" which expects a 5-digit ZIP code with an optional +4 extension. "abc" doesn't match.

Pattern validation errors are especially confusing because:

  1. The JSON escaping (\\d in the schema JSON becomes \d in the regex)
  2. Regex syntax itself is hard to read
  3. The error message shows the regex, not an explanation

Fix

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "address": {
    "city": "San Francisco",
    "zip": "94105"
  }
}

Debugging Pattern Errors

When a pattern error appears:

  1. Copy the regex from the schema (remove one level of escaping)
  2. Test it against your input in a regex tester
  3. Check for common regex gotchas: anchoring (^ and $), case sensitivity, Unicode handling

Error 7: Format Validation Failure

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "not-an-email",
  "role": "admin"
}

Error Message

Validation Error: /email: format validation failed (expected "email")

Why It Happens

JSON Schema's format keyword provides semantic validation beyond type checking. "format": "email" requires the string to look like an email address. The validation is intentionally loose — it doesn't check that the domain exists or that the mailbox is valid — but "not-an-email" doesn't come close.

Fix

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

Supported Formats

FormatExampleCommon Gotchas
emailuser@example.comSome validators reject + in local part
urihttps://example.comRelative URIs fail
date-time2026-06-29T12:00:00ZMust be RFC 3339, not ISO 8601 without timezone
date2026-06-29YYYY-MM-DD only
time12:00:00Must include seconds
ipv4192.168.1.1Leading zeros often fail
ipv6::1Must be colon-separated hex
uuidf47ac10b-58cc-4372-a567-0e02b2c3d479Hyphens required

Error 8: Array Constraint Violations

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "tags": ["javascript", "javascript", ""]
}

Error Message

Validation Error: /tags: duplicate elements found (values must be unique)
Validation Error: /tags/2: minimum length is 1, got 0

Why It Happens

The tags field requires unique items ("uniqueItems": true) and each item must be a non-empty string. This input violates both constraints: "javascript" appears twice, and the empty string is too short.

Fix

"tags": ["javascript", "programming"]

Error 9: Additional Properties Not Allowed

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "favorite_color": "blue"
}

Error Message

Validation Error: /: additional property 'favorite_color' not allowed

Why It Happens

The schema has "additionalProperties": false. Any key not defined in properties (or matched by patternProperties) is rejected. This is a common source of friction when:

  • You add a new field to your application but forget to add it to the schema
  • A consumer sends a misspelled property name
  • You migrate from a loose schema to a strict one

Fix

Either remove the extra property:

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin"
}

Or add it to the schema:

"properties": {
  ...
  "favorite_color": {
    "type": "string"
  }
}

Error 10: Nested Object Validation Failure

Bad Input

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "address": {}
}

Error Message

Validation Error: /address: required property 'city' not found

Why It Happens

The address property is an object with its own required array. Even though address itself is not required at the top level, if it's present, its contents must satisfy the nested schema.

Fix

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "role": "admin",
  "address": {
    "city": "San Francisco"
  }
}

Putting It All Together: A Debugging Workflow

When a JSON payload fails validation:

  1. Read the error path. The /address/zip path tells you exactly where the problem is. Start there.
  2. Check the type first. Is the value a string when an integer is expected? That's the most common error.
  3. Check null values. JSON Schema separates "absent key" (fails required) from "null value" (fails type).
  4. Copy-paste to a validator. Paste the JSON and schema into the JSON Schema validator to get formatted error messages.

FAQ

Why does my valid JSON fail JSON Schema validation?

Probably one of: wrong type (string instead of number), missing a required field, or an extra property that the schema doesn't allow. Check the error path first.

What's the difference between required and minLength?

required checks that a key exists in the object. minLength checks that a string value has at least N characters. A key with value "" passes required but fails minLength: 1.

Does JSON Schema validate null values?

It depends on the type keyword. If a property has "type": "string", a null value fails. If you want to allow null, use "type": ["string", "null"].

Why does additionalProperties:false reject my key when it's defined in properties?

This usually means you have a typo in the key name. Check for case sensitivity, trailing spaces, and Unicode normalization differences.

Can I use JSON Schema to validate API request bodies?

Yes, and you should. Many frameworks (FastAPI, Express with express-json-validator, ASP.NET) support JSON Schema validation on incoming requests. It's the most reliable way to catch malformed input early.

Where can I test JSON Schema validation without writing code?

The JSON Schema validator lets you paste both schema and data side by side, with line-level error highlighting and formatted error messages. It supports drafts 4, 7, and 2020-12.