[fix][broker] Keep accepting Avro named type references written as objects - #26586
Merged
Merged
Conversation
…jects
Avro 1.12.2 changed the schema parser so that a reference to a named
type must be written as the bare name (AVRO-4176). Up to Avro 1.12.1 the
reference could also be written as an object whose "type" is the name,
for example {"type": "org.example.shapes.Color"}, and the parser
resolved it to the named type while ignoring any other attribute.
After the Avro upgrade such schema definitions fail with
SchemaParseException: A schema "type" MUST be a primitive type or one
of "enum", "fixed", "record", "error", "array" or "map".
They were accepted and stored by the schema registry before, and
clients may still produce them, so the broker fails to validate, look
up and check compatibility of these schemas and clients fail to consume
from topics whose stored schema uses this form.
Rewrite such objects to the bare name before a schema definition is
handed to the Avro parser. The rewrite in pulsar-common follows the
schema structure, so field defaults and other JSON values are never
modified, and returns the input unchanged when there is nothing to
rewrite. The broker parses schema definitions through a single helper
in StructSchemaDataValidator, which also applies the compatible name
validator, and the client applies the rewrite in SchemaUtil and
GenericJsonRecord. Stored schema data is not modified.
lhotari
requested review from
Technoboy-,
dao-jun,
david-streamlio,
merlimat and
nodece
September 15, 2026 09:11
dao-jun
approved these changes
Sep 15, 2026
merlimat
approved these changes
Sep 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
#24617 upgraded Avro to 1.12.x. Avro 1.12.2 changed the schema parser so that a reference to a named type must be written as the bare name (AVRO-4176, apache/avro#3772). Up to Avro 1.12.1 the parser also accepted the reference written as an object whose
typeis the name, and resolved it to the named type while ignoring any other attribute of the object:{ "type": "record", "name": "Drawing", "namespace": "org.example.shapes", "fields": [ {"name": "background", "type": {"type": "enum", "name": "Color", "namespace": "org.example.shapes", "symbols": ["RED", "BLUE"]}}, {"name": "outline", "type": {"type": "org.example.shapes.Color"}} ] }With Avro 1.12.2 this fails with:
Such schema definitions were accepted by the broker and stored in the schema registry before the upgrade, and clients that hand-write or generate schemas may still produce them. After the upgrade the broker fails to parse them when validating a schema, when looking up an existing version of a schema, and when checking compatibility, and clients fail to parse them when consuming from a topic whose stored schema uses this form. The upgrade must not start rejecting schemas that were valid before, in the same spirit as #25193 restored the previous name validation.
Modifications
AvroSchemaCompat.normalizeNamedTypeReferences()topulsar-common, which rewrites{"type": "name"}objects to the bare"name"before a schema definition is handed to the Avro parser, reproducing the pre-1.12.2 behaviour. The rewrite follows the schema structure (the schema itself, field types, array items, map values and union members), so field defaults and other JSON values are never touched, and it returns the input unchanged when there is nothing to rewrite or the input is not JSON.StructSchemaDataValidator.parseAvroSchema()as the single broker-side way of parsing a schema definition (compatible name validator + the rewrite above) and use it inStructSchemaDataValidator,SchemaRegistryServiceImpl,AvroSchemaBasedCompatibilityCheckandJsonSchemaCompatibilityCheck, which each created their own parser before.SchemaUtil.parseAvroSchema()andGenericJsonRecord, which parse the schema definitions received from the broker.The stored schema data is not modified; the rewrite only affects what is passed to the parser.
Verifying this change
This change added tests and can be verified as follows:
AvroSchemaCompatTest: the rewrite in every schema position, nested records, a top-level reference, field defaults being left alone, and unchanged/invalid input being returned as is.SchemaDataValidatorTest:AVROandJSONschema data using the legacy form is accepted and parses to the named type.BaseAvroSchemaCompatibilityTest(Avro and JSON compatibility checks): the legacy and the bare name form of a schema are fully compatible with each other.SchemaUtilTest: the client parses the legacy form to the same schema as the bare name form.Does this pull request potentially affect one of the following parts:
If the box was checked, please highlight the changes
Schema definitions that use the pre-Avro-1.12.2 object form for named type references are accepted again by the broker and the client; nothing changes for other schemas.
Documentation
doc-not-needed