A team publishes events to a topic read by many independent consumers. They need to add a field with no default value to the event schema. Which registry compatibility mode permits that, and what is the mode really constraining?
Show the full answer Hide the answer
The deciding property
A compatibility mode is a statement about deployment order, not about safety. That single reframing answers every question of this shape:
| Mode | Reader/writer rule | Deployment order it buys |
|---|---|---|
| BACKWARD | A reader on the new schema can read data written with the old one | Upgrade consumers first |
| FORWARD | A reader on the old schema can read data written with the new one | Upgrade producers first |
| FULL | Both hold | Either order |
| NONE | Nothing is checked | Coordinate manually |
Adding a field with no default is forward compatible: an old reader encounters an unknown field and ignores it. It is not backward compatible, because a new reader encountering historical data has no value for the field and no default to fall back on. So the change is permitted under FORWARD, and the price is that every producer must be upgraded before any consumer adopts the new schema.
Why the other options fail
- BACKWARD is the default in the common registry implementations, which is exactly why it is the instinctive answer — and under BACKWARD this change is rejected. The fix people reach for, giving the field a default, works precisely because it stops being the change in the question: a field with a default is optional, and optional fields are addable under any mode.
- FULL rejects it for the same reason BACKWARD does. FULL is the correct default when you genuinely cannot control deployment order — many teams, no coordination — and its price is permanent: only optional fields may ever be added or removed, forever.
- NONE rests on a false premise. The change is not inherently unsafe; it is unsafe in one direction. Choosing NONE turns the registry from a safety mechanism into a catalogue, and the breakage simply moves to the consumer that deploys at the wrong moment.
What would flip the decision
The transitive variants. BACKWARD_TRANSITIVE and FORWARD_TRANSITIVE check the new schema against every previous version rather than only the most recent one. The non-transitive modes are sufficient when consumers are never far behind and history is not replayed.
They are insufficient the moment the topic is used as an event store or a source of replay, because a new consumer starting from the beginning will read data written under schema version 1, and a chain of individually-compatible steps can be collectively incompatible. If you replay, you need transitive, and the cost is that schema evolution becomes much more constrained.
Common weak answers
"Just use FULL for everything, it is the safest" sounds prudent and quietly forbids ever adding a required field or removing a field for the life of the topic. Pick the mode from how you deploy, write that reasoning down next to the topic, and revisit it when the consumer population changes.