Pydantic ValidationError: 'Field Required' and How to Read It

Pydantic's ValidationError looks noisy but it's the most helpful error you'll get — it lists every field that failed and why. Learn to read it once and you'll fix these in seconds.

BytExplorer 6 min read July 18, 2026

You construct a model and Pydantic refuses:

pydantic_core._pydantic_core.ValidationError: 1 validation error for User
email
  Field required [type=missing, input_value={'name': 'Ada'}, input_type=dict]

A ValidationError means the data you passed didn't satisfy the model's schema. Unlike most exceptions, this one is a report: it tells you the model (User), the field (email), the reason (Field required), and what you actually passed ({'name': 'Ada'}). Read those four things and the fix is obvious.

'Field required' means a mandatory field is missing

In Pydantic v2, a field with no default is required:

from pydantic import BaseModel

class User(BaseModel):
    name: str
    email: str          # required

User(name="Ada")        # ❌ ValidationError: email Field required

Two fixes, depending on intent:

email: str | None = None      # optional, defaults to None
# or
email: str = "[email protected]"  # optional, with a real default

If the field should be required, then the bug is upstream — you're not passing email when you build the model. Trace where the dict comes from.

Type errors: 'Input should be a valid integer'

age
  Input should be a valid integer [type=int_parsing, input_value='twenty']

The value can't be coerced to the declared type. Pydantic will turn "25" into 25, but not "twenty". Either send a real number or change the field type to accept what you're actually giving it.

Read all the errors at once

Pydantic validates every field and reports them together — "3 validation errors for User" means three separate problems. Don't fix one and re-run three times. To handle them in code, catch the error and inspect .errors():

from pydantic import ValidationError

try:
    User(**payload)
except ValidationError as e:
    for err in e.errors():
        print(err["loc"], err["msg"])   # ('email',) 'Field required'

.errors() gives you a clean list of loc (which field) and msg (what's wrong) — the same structure FastAPI puts in a 422 response body.

Cause: you're on Pydantic v2 with v1 habits

If you upgraded and things broke, v2 changed some names: .dict().model_dump(), .parse_obj().model_validate(), and Optional[x] without a default is now still required (you must write = None). Many "sudden" ValidationErrors are really a v1→v2 migration gap.

The checklist

  1. Read the field name, the msg, and the input_value — they name the problem.
  2. Field required → pass the field, or give it a default (= None).
  3. Type error → send the right type, or widen the field's type.
  4. Use except ValidationError as e: e.errors() to get a clean, structured list.
  5. Just upgraded? Check for v1→v2 API changes (model_dump, model_validate).

Frequently Asked Questions

How do I make a Pydantic field optional?

Give it a default value. email: str | None = None makes it optional and defaults to None. A field declared with just a type and no default is required in Pydantic v2, even if the type is Optional.

How do I see all the validation errors, not just one?

Catch the exception and call .errors()except ValidationError as e: print(e.errors()). It returns a list of dicts with loc and msg for every field that failed, so you can fix them all in one pass.

Why does Pydantic reject '25' as a string for an int field?

It usually doesn't — Pydantic coerces "25" to 25. It rejects values it can't parse into the type, like "twenty". If you want strict typing that refuses even coercible strings, use a StrictInt or enable strict mode.

Put it into practice

Stop reading, start building

This pairs with a hands-on BytExplorer course — do it on your own machine and actually keep the skill.

More in Troubleshooting