{{ summary.heading }}
{{ summary.primary }}
{{ summary.line }}
{{ badge.label }}
Writer {{ releasedVersionLabel }} Reader {{ proposedVersionLabel }} Backward Forward
Avro schema compatibility inputs
Use the Kafka subject or event contract name, such as customer-value or payment-event-value.
Choose the same policy you intend to enforce in Schema Registry before shipping the proposed schema.
Keep aliases on when the proposed schema intentionally renames records or fields with Avro aliases.
Use strict for contract reviews where decimal scale, timestamps, dates, UUIDs, and other logical annotations must not drift silently.
For non-transitive modes, only the latest released schema is checked. For transitive modes, every schema in this history is checked.
{{ releasedDropHint }}
The proposed schema is compared as the new writer, reader, or both depending on the selected compatibility mode.
{{ proposedDropHint }}
Results update as schemas or policy settings change.
Use 25 to 500 findings; lower values keep large schema comparisons responsive.
rows
Turn off when you only want release blockers and compatibility warnings.
Include non-blocking advisory rows
Severity Direction Version Schema path Finding Release action Copy
{{ row.severityText }} {{ row.direction }} {{ row.version }} {{ row.path }} {{ row.message }} {{ row.action }}
No compatibility findings
The parsed schemas did not produce release blockers or advisory rows for the selected policy.
Area Status Evidence Release action Copy
{{ row.area }} {{ row.status }} {{ row.evidence }} {{ row.action }}
{{ registryRequestText }}
{{ jsonText }}
Customize
Advanced
:

Introduction:

Avro lets compact binary data move through systems that do not all upgrade at the same time. The schema used by a producer describes what was written, and the schema used by a consumer describes what can be read. Compatibility work starts at that boundary: the proposed contract may be valid Avro JSON, but the release is safe only if readers and writers can still resolve the same records, fields, names, unions, enums, fixed values, and logical annotations.

Event streams make that problem visible. A Kafka topic can keep old events for days, months, or years, while producers, stream processors, warehouse loaders, and API consumers deploy on different schedules. A schema change that works for new events may still fail during replay, backfill, disaster recovery, or a late consumer deployment. Compatibility modes are the vocabulary teams use to say which direction of upgrade must keep working.

Common Avro compatibility situations
Situation Compatibility pressure Common mistake
Consumers deploy before producers New readers must understand data already written with the old schema. Adding a reader field without an Avro default.
Producers deploy before consumers Old readers must tolerate records written with the proposed schema. Removing a field that an old reader still expects with no fallback.
Topics are replayed from history The proposed schema must be checked against more than the latest release. Using a latest-only mode when early versions can still be read.
Names or types are cleaned up Aliases, logical types, defaults, and union branches must preserve meaning. Treating a rename or annotation change as cosmetic.
Schema evolution depends on read direction Released old writer or reader Proposed new writer or reader Backward new reader reads old data Forward old reader reads new data

Backward compatibility is the common choice when consumers may rewind and read older data with a newer schema. Forward compatibility protects older consumers when producers start writing the new shape first. Full compatibility asks for both directions. Transitive modes widen the review from the latest released schema to every schema version in the supplied history.

Many Avro changes are safe only because a specific resolution rule exists. A new reader field needs a default when old data lacks the field. A writer enum symbol that disappeared from the reader side needs a valid enum default or decoding can fail. A named type can survive a rename only when aliases map the old name to the new one. A fixed value keeps its byte width. Logical types add another layer because the underlying primitive may stay the same while the meaning changes from one timestamp, decimal, date, or UUID annotation to another.

A compatibility pass is a contract check, not a complete release approval. It cannot prove that generated classes, downstream tables, dashboards, consumer code, or business processes are ready for the new meaning. Strong schema reviews keep syntax, direction, history depth, defaults, aliases, logical annotations, registry policy, and consumer testing as related but separate decisions.

How to Use This Tool:

Use the checker as a release review for a proposed Avro contract. The most useful inputs are the same subject name, compatibility mode, released history, and proposed schema that will be reviewed before registration.

  1. Enter the Schema Registry subject so the generated evidence uses the contract name you intend to update.
  2. Choose the Compatibility mode. Use BACKWARD for new readers against old data, FORWARD for old readers against new data, FULL when both directions matter, and a transitive mode when all released versions are still in replay scope.
  3. Set Name and alias matching. Reader aliases are the usual Avro rename path; exact-name review is stricter and will flag renamed fields or named types without accepted aliases.
  4. Set Logical type policy. Strict review is the safer contract setting when decimal precision or scale, timestamps, dates, UUIDs, and other logical annotations carry business meaning.
  5. Paste Released schema history from oldest to newest. The field accepts a JSON array of schemas or separate schema documents split by a line containing only three hyphens.
  6. Paste the Proposed schema, or browse for AVSC, JSON, or TXT files. Use Format after parsing is clean so syntax problems do not hide compatibility findings.
  7. Read Compatibility Ledger for path-level blockers, Rule Summary for policy decisions, Compatibility Risk Mix for severity counts, and Registry Request only as starter text for your real registry workflow.

Interpreting Results:

A passing result means the parsed schemas produced no critical or high-severity blocker under the selected direction, history depth, alias policy, and logical type policy. It does not prove that all producers and consumers are deployed or that a registry product will make every decision the same way.

Avro compatibility finding severity guide
Severity Typical meaning Release response
Critical Schema resolution or Avro structure can fail, such as missing defaults, incompatible type changes, enum symbol loss, fixed-size drift, duplicate fields, nested unions, or unresolved references. Do not register under the selected policy until the schema or rollout plan changes.
High A default or logical-type problem is serious enough to block strict review. Keep the contract stable, repair the default, or move to a deliberate migration path.
Medium A fallback may exist, but the semantic effect needs review, such as an enum default absorbing removed symbols. Confirm the fallback is acceptable to consumers before registering.
Low A non-blocking drift or advisory finding deserves tests or reviewer attention. Record the decision and keep contract tests around the changed path.
Info The rule usually resolves, such as a supported primitive promotion or an ignored writer field. Keep the change intentional and verify downstream expectations.

The Rule Summary is useful for spotting policy mismatches. A result can pass in BACKWARD and fail in FORWARD because the reader and writer roles are reversed. A latest-only pass can also hide an older replay problem that appears only after switching to BACKWARD_TRANSITIVE, FORWARD_TRANSITIVE, or FULL_TRANSITIVE.

Treat NONE as a syntax and structure review. Compatibility direction checks are skipped in that mode, but malformed schema nodes, duplicate fields, invalid defaults, nested unions, and parse errors can still show up because those issues matter before any registry policy is considered.

Technical Details:

Avro schema resolution is directional. Data is encoded with a writer schema and decoded with a reader schema. If the reader can match the writer's type, name, field, union branch, enum symbol, or promoted primitive, decoding can continue. If the reader needs a value that the writer never supplied and no default exists, resolution fails.

Compatibility modes are built from that writer-reader relationship. Backward checks use each released schema as the writer and the proposed schema as the reader. Forward checks reverse the roles. Full checks run both directions. Transitive modes repeat the required direction checks across every released schema in the supplied history instead of only the latest version.

Rule Core

Avro compatibility rule stages
Stage Rule Evidence in results
Parse inputs Read released schemas from a JSON array or hyphen-separated documents, then parse the proposed schema. Parse findings and the released version count appear in the rule summary.
Check Avro shape Validate named references, record fields, duplicate field names, enum symbols, enum defaults, fixed sizes, union branch rules, and default values against the first matching branch. Structure rows are reported before direction-specific compatibility rows.
Select history scope Use the latest released schema for non-transitive modes, or all released schemas for transitive modes. Rule summary reports latest-only or all-history scope.
Compare directions Backward compares released writer to proposed reader; forward compares proposed writer to released reader. Ledger rows carry backward, forward, structure, or parse direction labels.
Rank findings Critical and high rows are blockers. Medium, low, and info rows explain warnings, advisories, and compatible changes. The ledger is sorted by severity and capped by the selected finding limit.

Primitive promotion follows Avro's resolution rules. An int writer can be read as long, float, or double; long can promote to float or double; float can promote to double; and string and bytes can promote to each other. Other primitive substitutions are incompatible unless a union branch keeps a compatible old shape available.

Avro compatibility rule examples
Schema element Compatible pattern Risky or blocking pattern
Reader field A new reader field has an Avro default that matches the field schema. The reader adds a required field and old data has no value for it.
Record, enum, or fixed name The name is stable, or the reader provides an alias for the released name when aliases are accepted. A named type or field is renamed without a matching reader alias.
Union The reader has a branch that can resolve the writer's selected branch, with valid first-branch defaults when a field default is present. A writer branch disappears, duplicate branches are introduced, or a union directly contains another union.
Enum The reader accepts every writer symbol, or a valid reader enum default covers unknown writer symbols. A writer symbol is removed and the reader has no usable enum default.
Fixed Name resolution succeeds and the byte width stays the same. The fixed size changes, even if the new name looks related.
Logical type Decimal precision and scale, timestamp annotations, dates, UUIDs, and other logical meanings remain intentional under the selected policy. The underlying primitive stays compatible while the logical annotation changes in a contract-sensitive way.

Defaults are especially important for records and unions. Avro uses a reader field default only when the writer did not provide that field, and union defaults must correspond to the first branch that matches. That is why a nullable field commonly starts with null and uses null as the default, instead of placing null later in the union.

Logical type policy changes the severity of annotation drift. Decimal precision or scale differences are treated as high-risk because the numeric contract changes. Other logical-type changes become high severity under strict review and lower-severity advisory findings when the policy allows looser review. Ignoring logical types may be useful for exploratory checks, but it should not replace consumer tests when the annotation affects generated code or stored meaning.

Limitations and Privacy Notes:

The analysis runs in the browser after the page loads. Schema text, imported files, generated reports, and copied registry starter text stay in the current browser session unless you export or share them.

  • Use your registry's own compatibility endpoint before registering a production schema, because registry products and configured policies can differ.
  • Generated registry commands are starter text. Adapt the URL, authentication, subject naming, content type, and release process before use.
  • Compatibility does not replace producer and consumer integration tests, generated-code checks, replay tests, or downstream data contract review.

Worked Examples:

Optional field added for replay

A proposed customer event adds region as a string with default "us-east-1". In backward mode, old events can be read by the proposed reader because the missing field has a value to use during decoding. The ledger should show an informational default row rather than a blocker.

Field shape changed too quickly

A released email string becomes a nested EmailAddress record with no compatible union branch. The checker reports a critical type change because a reader expecting the old string cannot resolve the new record shape in the selected direction.

Latest-only review misses history

The latest released schema may be compatible while an older version still in replay lacks an enum default or field fallback needed by the proposed reader. Switching from BACKWARD to BACKWARD_TRANSITIVE brings that older version into the comparison set and exposes the release risk.

FAQ:

Is BACKWARD the safest Avro mode?

Backward compatibility is common for Kafka replay because new consumers can read old data. It is not enough when old consumers must read new data, or when every historical version must remain readable.

Why does a new field need a default?

Old data does not contain the new field. A reader default gives the decoder a value to use when the writer schema lacks that field.

Can aliases make every rename safe?

No. Aliases can support Avro name resolution for fields and named types, but generated classes, downstream storage, queries, and business meaning still need review.

Why did a logical type warning appear when the primitive type did not change?

Logical types add meaning to primitives. A long timestamp, a date int, a decimal bytes value, or a UUID string can keep the same underlying Avro type while consumers interpret the value differently.

Why does NONE still show findings?

NONE skips compatibility direction checks, but parse and Avro structure checks still run so malformed schema documents are visible before a registry or build step sees them.

Glossary:

Writer schema
The schema used when data was encoded or will be produced.
Reader schema
The schema used by a consumer while decoding data.
Backward compatibility
New readers can read data written with older schemas.
Forward compatibility
Older readers can read data written with the new schema.
Full compatibility
Both backward and forward checks are expected to pass.
Transitive compatibility
The proposed schema is compared against all released versions in scope, not just the latest one.
Logical type
An Avro annotation that gives a primitive or complex storage type a more specific meaning, such as decimal, date, timestamp, or UUID.