tiangolo/fastapi · error · PydanticV1NotSupportedError

pydantic.v1 models are no longer supported by FastAPI…

Error message

pydantic.v1 models are no longer supported by FastAPI. Please update the model {obj!r}.

What it means

PydanticV1NotSupportedError raised inside jsonable_encoder (encoders.py:342). When FastAPI walks the response to serialize it, is_pydantic_v1_model_instance(obj) returns True for a legacy pydantic.v1.BaseModel instance, and FastAPI (which is pydantic-v2-only) refuses to encode it. The message names the offending model via {obj!r}.

Solutions

  1. Migrate the model to pydantic v2: change `from pydantic import BaseModel` (drop the .v1), and adapt validators/config to v2 (model_config, @field_validator).
  2. If you must keep a v1 model, convert it before returning: return obj.dict() (v1) or pydantic_v1 parse to a v2 model.
  3. Search the codebase for `pydantic.v1` imports and remove/replace them.
  4. Ensure third-party objects returned are v2 models or plain dataclasses/dicts.

Example fix

// before
from pydantic.v1 import BaseModel

class Item(BaseModel):
    name: str

@app.get("/items/{i}", response_model=Item)
def read(i: int):
    return Item(name="x")  # -> PydanticV1NotSupportedError

// after
from pydantic import BaseModel, ConfigDict

class Item(BaseModel):
    model_config = ConfigDict()
    name: str

@app.get("/items/{i}", response_model=Item)
def read(i: int):
    return Item(name="x")
Defensive patterns

Strategy: type-guard

Validate before calling

# Reject pydantic v1 models before they reach jsonable_encoder
try:
    from pydantic.v1 import BaseModel as V1Model
except ImportError:
    V1Model = None

def assert_v2(obj):
    if V1Model is not None and isinstance(obj, V1Model):
        raise TypeError(f"pydantic v1 model not supported: {obj!r}")
    return obj

Type guard

def is_pydantic_v1(obj) -> bool:
    try:
        from pydantic.v1 import BaseModel as V1Model
    except ImportError:
        return False
    return isinstance(obj, V1Model)

Try / catch

from fastapi.encoders import jsonable_encoder
try:
    data = jsonable_encoder(obj)
except Exception as e:
    if "pydantic.v1" in str(e):
        data = obj.dict()  # v1 fallback, then migrate
    else:
        raise

Prevention

When it happens

Trigger: An endpoint returns (or a response_model produces) an instance of a pydantic.v1 model — e.g. a model imported from pydantic.v1, a third-party object built on v1, or code that still uses the v1 compatibility shim — and jsonable_encoder tries to serialize it.

Common situations: Migrating from FastAPI 0.99 (pydantic v1) to 0.100+/1.x (pydantic v2) without converting models; a dependency/library returning pydantic.v1 objects; mixing `from pydantic.v1 import BaseModel` leftovers; ORJSONResponse/custom encoder receiving a v1 model.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/bc673065736fdc29. Report an issue: GitHub.

Appendix: source

Thrown at fastapi/encoders.py:342

                    include=include,
                    exclude=exclude,
                    by_alias=by_alias,
                    exclude_unset=exclude_unset,
                    exclude_defaults=exclude_defaults,
                    exclude_none=exclude_none,
                    custom_encoder=custom_encoder,
                    sqlalchemy_safe=sqlalchemy_safe,
                )
            )
        return encoded_list

    if type(obj) in ENCODERS_BY_TYPE:
        return ENCODERS_BY_TYPE[type(obj)](obj)
    for encoder, classes_tuple in encoders_by_class_tuples.items():
        if isinstance(obj, classes_tuple):
            return encoder(obj)
    if is_pydantic_v1_model_instance(obj):
        raise PydanticV1NotSupportedError(
            "pydantic.v1 models are no longer supported by FastAPI."
            f" Please update the model {obj!r}."
        )
    try:
        data = dict(obj)
    except Exception as e:
        errors: list[Exception] = []
        errors.append(e)
        try:
            data = vars(obj)
        except Exception as e:
            errors.append(e)
            raise ValueError(errors) from e
    return jsonable_encoder(
        data,
        include=include,
        exclude=exclude,
        by_alias=by_alias,

View on GitHub (pinned to 3e8d1526d8)