Avro Schema Compatibility Validator
Compare released and proposed Avro schemas locally, find writer-reader blockers, and review compatibility before a registry release.{{ summaryHeading }}
{{ summaryLine }}
| Severity | Direction | Version | Schema path | Finding | Release action | Copy |
|---|---|---|---|---|---|---|
| {{ severityLabel(row.severity) }} | {{ row.direction }} | {{ row.version }} | {{ row.path }} | {{ row.message }} | {{ row.action }} | |
| No blocker or warning rows for the selected policy. Turn on advisory rows for the full local audit trail. | ||||||
{{ exportAnnouncement }}
The chart renderer is unavailable; canonical severity counts remain in the findings handoff.
| Review area | Status | Evidence | Release action | Copy |
|---|---|---|---|---|
| {{ row.area }} | {{ row.status }} | {{ row.evidence }} | {{ row.action }} |
{{ registryRequestText }}
Avro records carry compact data because the writer does not repeat field names and type information with every value. The schema used to write the data therefore matters whenever a later application reads it. Schema evolution is the discipline of changing that contract without making stored events or newly produced events unreadable.
Compatibility is directional. A proposed schema may work as a reader of old data while an old reader fails on data written with the proposal. Long-lived topics add another choice: compare only with the latest released schema, or protect replay against every version still retained in history.
| Policy | Reader | Writer | Main concern |
|---|---|---|---|
| Backward | Proposed schema | Released schema | New consumers must read older stored data. |
| Forward | Released schema | Proposed schema | Older consumers must read newly written data. |
| Full | Both directions | Both directions | Producer and consumer upgrades need freedom in either order. |
| Transitive | Depends on direction | Every released version | Replay or retention reaches beyond the latest schema. |
Field additions and removals cannot be judged from names alone. A reader field missing from the writer needs a valid default. A renamed record or field normally needs an alias on the reader side. Union branches, enum symbols, fixed sizes, numeric promotions, and logical types such as decimal or timestamp can each change whether a writer value resolves into the reader schema.
Defaults are especially easy to misunderstand. They fill a field when a reader encounters data written without that field; they do not make the field optional when encoding new records. For a union, the default must match the first compatible branch, so changing branch order can break an otherwise familiar nullable-field pattern.
A local compatibility result is release evidence, not the registry's verdict. Registry configuration, implementation-specific parsing, references shared across schema documents, and real serializer behavior can still change the outcome. Keep the registry check and representative producer-consumer tests in the release path.
How to Use This Tool:
Match the review settings to the policy that will govern the subject in production.
- Paste Released schema history from oldest to newest. Use one schema, a JSON array, a supported history object, or separate complete schema documents with a line containing three dashes.
- Enter the Schema Registry subject and paste one complete Proposed schema. Every named reference must be defined in that document.
- Choose Compatibility mode. Non-transitive modes compare only with the newest released version; transitive modes compare with the full supplied history.
- Set Name and alias matching and Logical type policy to the intended release rules. Reader aliases and strict logical-type review are the conservative defaults.
- Read Compatibility findings from the highest severity downward. Clear every critical and high row before using the generated registry request or registering the proposal.
Interpreting Results:
Compatible means no critical or high finding remains under the selected direction, history scope, alias policy, and logical-type policy. Medium and low findings still deserve review because an enum fallback or changed annotation can preserve Avro readability while changing application meaning.
Blocked means the proposal fails the local structural review or at least one selected writer-reader comparison. Follow the direction and version on each row: backward findings describe a proposed reader facing released data, while forward findings describe a released reader facing proposed data.
Mode NONE checks JSON parsing and bounded Avro structure only. It does not establish compatibility. Even a clean directional result should be confirmed against the production registry and the serializers used by the actual producers and consumers.
Technical Details:
Avro resolution compares a writer schema with a reader schema. The writer describes the encoded datum; the reader describes the shape requested by the consumer. Compatibility modes choose which released or proposed schema occupies each role and how much history participates.
Rule Core
The review parses each schema, builds its named-type registry, checks structural validity, and then walks matching writer and reader nodes. The first incompatible rule at a path produces a finding with its direction and released version.
| Schema feature | Compatible path | Blocking path |
|---|---|---|
| Primitive type | Exact match, or writer promotion from int to long, float, or double; from long to float or double; from float to double; and between string and bytes. | No exact match or declared promotion path. |
| Reader field | A matching writer field exists, or the reader field has a valid default. | The reader needs a field absent from the writer and no default is present. |
| Record, enum, or fixed name | Names match, or the selected alias policy supplies a match. | Name changes without an accepted alias. |
| Union | Every writer branch has a reader branch that can resolve it. | At least one possible writer branch has no readable counterpart. |
| Enum | Reader accepts each writer symbol, or has an accepted enum default. | A writer symbol is missing and no valid fallback exists. |
| Fixed | Name and byte size remain compatible. | Fixed size changes or the name cannot be resolved. |
| Logical type | Annotations follow the selected policy; decimals retain matching precision and scale. | Strict policy sees changed logical meaning, or decimal precision or scale changes. |
Structural checks run before directional comparisons. They reject unresolved named references, malformed schema nodes, nested unions, duplicate primitive union branches, missing record names or field types, duplicate field names, empty or duplicate enum symbols, invalid enum defaults, and non-positive fixed sizes. A field default is checked against its type, including the first union branch.
Compatibility scope
| Mode family | Backward comparison | Forward comparison | History |
|---|---|---|---|
BACKWARD | Released writer to proposed reader | Not run | Latest only |
FORWARD | Not run | Proposed writer to released reader | Latest only |
FULL | Released writer to proposed reader | Proposed writer to released reader | Latest only |
| Transitive variants | As selected | As selected | Every supplied version |
NONE | Not run | Not run | Structure only |
Critical and high findings are release blockers. Medium and low findings remain non-blocking warnings. Information rows cover safe promotions, defaults, and ignored writer fields only when Advisory rows is enabled; that display choice never changes the blocker count.
Limitations and Privacy Notes:
Schema text is evaluated in the browser and no registry is contacted. The subject label only names local evidence and the generated request.
- The review is a bounded compatibility model, not a complete replacement for an Avro library or Schema Registry.
- Named references must be defined within each pasted schema document; external reference graphs are not resolved.
- The finding limit changes visible rows only. It does not reduce canonical counts or remove findings from the complete result.
- Aliases accepted from both sides are a broader review policy than ordinary reader-alias resolution. Use it only when that matches the release process.
Worked Examples:
New reader field without a default
A proposed reader adds region as a required string while older records have no such field. Under a backward check, the finding is critical because the reader cannot construct region from released data. Adding a valid default, or staging a compatible nullable union whose default matches its first branch, clears that specific rule.
Long to int narrows old values
A released writer stores an identifier as long, while the proposed reader changes it to int. Avro has no promotion from long to int, so backward compatibility is blocked. Keeping long preserves readability; changing the subject is safer when a genuinely different contract is intended.
References:
- Apache Avro Specification 1.12.0, Apache Software Foundation.
- Schema Evolution and Compatibility Types, Confluent.
- How to read and write Avro files with Spark, Simplified Guide.