Library / SDK
pyeve/cerberus avatar
pyeve/cerberus

Cerberus: schema validation for Python dictionaries

Lightweight, extensible data validation library for Python

3,281 stars246 forksPythonISC

At a glance

What is it?
Cerberus is a dependency-free validation library that checks dictionaries against a schema and reports errors per field. It suits API payload checks and config parsing, and it is a poor fit for validating arbitrary objects or streaming data.
Who is it for?
Adopt Cerberus if you validate dictionary-shaped input such as JSON payloads, config files or form data and want the rules written as plain Python dicts with no runtime dependencies. Do not adopt it if your data is not a mapping, if you need to validate objects with attributes rather than keys, or if you expect validation to coerce types silently.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem Cerberus solves: validating dicts without writing a parser

Most Python code that accepts external input ends up with a pile of hand-written checks: is this key present, is it a string, is the number in range, is the nested list non-empty. Cerberus replaces that pile with a declarative schema. You describe the shape of a valid document once, as a dict, and the library walks the input against it and collects errors instead of raising on the first failure.

The README states the goal plainly: Cerberus is a lightweight and extensible data validation library for Python. The pyproject.toml describes it as a schema and data validation tool for Python dictionaries, and the keywords list validation, schema, dictionaries, documents and normalization. That keyword list is the most honest summary of the scope. Cerberus validates mappings. It is aimed at developers who receive documents from somewhere they do not control: HTTP request bodies, YAML or JSON config files, message payloads, form submissions. If your data already lives in a typed object, Cerberus is the wrong layer.

How validation works: a schema dict, a Validator, and an errors dict

The mechanism is a two-part contract. The schema is a plain dict whose keys are field names and whose values are rule dicts. The Validator holds the schema and exposes a validate method that takes the document. The README's opening example is the whole loop in three lines.

python
>>> v = Validator({'name': {'type': 'string'}})
>>> v.validate({'name': 'john doe'})
True

The return value is a boolean, and the interesting part is the side channel: after a failed validation the Validator carries an errors attribute describing what went wrong, keyed by field. That design choice is the reason Cerberus fits request handling. You can branch on a boolean and still hand the caller a structured explanation rather than a stack trace.

Rules are composable. A field can carry type, required, allowed values, ranges, and a nested schema for sub-documents, and the same rule vocabulary applies at each level. The README also lists normalization among the keywords, which means the library can rewrite values as part of validation rather than only accept or reject them. The README does not document the normalization rules in detail; that detail lives in the documentation site at docs.python-cerberus.org.

Extensibility is advertised as a first-class property: the README calls the library non-blocking and easily and widely extensible, allowing for custom validation. In practice that means custom rules and custom types can be registered rather than forked. The README does not give the registration API, so treat the extension surface as something to confirm in the docs before you build on it.

Installing Cerberus and validating a first payload

The README gives exactly one installation instruction, because the package is on PyPI. There is no build step, no compiled extension and no service to run.

bash
pip install cerberus

After that, the README's own example is the smallest useful program. It defines a schema with one string field and validates a document against it.

python
>>> v = Validator({'name': {'type': 'string'}})
>>> v.validate({'name': 'john doe'})
True

What you should see is True, because the document satisfies the single rule. Change the value to something other than a string and the call returns False instead; the README does not show that case, so confirm the shape of the errors attribute against the documentation for your installed version before you build error handling on top of it.

If you want to run the project's own tests, the README gives the commands. It suggests python setup.py test, or tox for the full matrix across supported interpreters, with pip install tox needed the first time. The pyproject.toml sets requires-python to >=3.7 and lists classifiers from Python 3.7 through 3.14 for both CPython and PyPy.

Where Cerberus stops being the right tool

The scope is mappings, and the library does not pretend otherwise. If your input is a list of records, you validate each element yourself. If your input is an object with attributes, you either convert it to a dict first or use a library built around object schemas. Cerberus will not walk attribute graphs for you.

A second boundary is that validation is a pass over a document that already exists in memory. There is nothing in the README about streaming, incremental validation or validating while parsing. For a large file you load it, then validate it.

A third point is less a limitation than a design consequence worth naming: the errors live on the Validator instance rather than being returned. Reusing a single Validator across threads or across interleaved validations means the errors attribute is shared state. The README does not discuss thread safety, so the safe reading is that a Validator is a per-validation object unless the documentation says otherwise.

Finally, the project's own versioning note is unusually candid. The README says micro releases polish a definite amount of features to glory, and adds that new bugs are inevitable. It also states that Cerberus is tested against CPython interpreters at least until half a year after their end of life. If you are pinned to an interpreter past that window, the README advises running the contributed test suite on your target system rather than assuming a release supports it.

Cerberus compared with schema libraries that validate objects

The closest conceptual alternative is a schema library built on Python's typing and dataclass machinery, where you declare a class and validation happens when you construct it. The difference is where the schema lives. In Cerberus the schema is data: a dict you can build at runtime, load from a file, merge, or generate. In a class-based validator the schema is code, which buys you static analysis and editor completion at the cost of runtime flexibility.

That distinction decides the choice. If your schemas come from configuration, from a database, or from a plugin, a dict-shaped schema is the only one that works without code generation. If your schemas are fixed and you want mypy to catch a typo in a field name, the class-based approach wins and Cerberus will feel like a stringly-typed detour.

The second difference is the error model. Cerberus collects errors for the whole document and exposes them as a mapping, which is what an API needs to return field-level feedback in one response. Validators that raise on the first problem give you a single exception and force you to re-run to find the next issue. For interactive forms, the collect-all model is the one you want.

A third difference is dependency weight. The pyproject.toml lists a single dependency, importlib-metadata, and only for Python versions below 3.8. On any modern interpreter Cerberus installs with nothing else. That matters in constrained environments where a validation library pulling in a typing backport and a date parser is not acceptable.

Maintenance, versioning and the ISC licence

The repository is not archived, and the last push was on 2026-09-19, which is days before this writing. The pyproject.toml declares version 1.3.8 and a Development Status classifier of Production/Stable. The default branch is named 1.3.x, which tells you the maintenance line is a minor series rather than a trunk.

Versioning follows semantic versioning, per the README, starting with Cerberus 1.2. Major releases break, minor releases add features, micro releases fix. The presence of an UPGRADING.rst at the repository root is consistent with that promise: breaking changes get a migration document rather than a changelog entry alone. The README does not describe a deprecation policy beyond the interpreter support window, and it does not document rollback.

Upgrade cost is mostly interpreter-driven. The README commits to testing against CPython interpreters until at least half a year after their end of life, and against the most recent PyPy as a release requirement. The pyproject.toml classifiers currently run from Python 3.7 to 3.14. When your runtime falls outside that set, the README's own advice is to run the contributed test suite on your target system.

Licensing is ISC, a permissive licence in the same family as MIT and BSD. The pyproject.toml references the LICENSE file rather than inlining the text, and the README points at the same file in the repository. ISC is short and permissive, but it is your own legal review that decides whether it fits your distribution model; nothing in the repository addresses that question.

Editorial conclusion

Adopt Cerberus if you validate dictionary-shaped input such as JSON payloads, config files or form data and want the rules written as plain Python dicts with no runtime dependencies. Do not adopt it if your data is not a mapping, if you need to validate objects with attributes rather than keys, or if you expect validation to coerce types silently. Before committing, verify two things against the documentation for your version: how normalization interacts with your field names, and whether the default allow_unknown setting matches how strict you want unknown keys to be.

Frequently asked questions

How do I install Cerberus?

The README states the package is on PyPI and gives a single command, pip install cerberus. There is no separate build step because the library has no compiled parts.

How do I use Cerberus to validate a dictionary?

Create a Validator with a schema dict, then call validate on the document. The README's example is Validator({'name': {'type': 'string'}}).validate({'name': 'john doe'}), which returns True.

Does Cerberus have any dependencies?

The README says it has no dependencies. The pyproject.toml lists only importlib-metadata, and only for Python versions below 3.8.

What Python versions does Cerberus support?

The pyproject.toml sets requires-python to >=3.7 and classifies support from Python 3.7 through 3.14 for CPython and PyPy. The README states interpreters are tested at least until half a year after their end of life.

What licence does Cerberus use?

The project is licensed under ISC, and the pyproject.toml points at the LICENSE file rather than restating the terms. The README refers to the same file for licence details.

How do I run the Cerberus test suite?

The README gives python setup.py test for a single run, or tox to test under all supported Python versions after installing tox with pip.

Official sources

  1. Issues
  2. License: ISC
  3. Project website
  4. pyeve/cerberus on GitHub
  5. README
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pyeve-cerberus.svg)](https://hysenlabs.com/projects/pyeve-cerberus)
Community notes

Community notes