apache/pulsar · error · InvalidSchemaDataException
Avro schema typed [UNION] is not supported
Error message
Avro schema typed [UNION] is not supported
What it means
StructSchemaDataValidator.checkAvroSchemaTypeSupported rejects an Avro schema whose root type is UNION. Pulsar's registry supports RECORD as the root of an Avro schema (plus scalar/array/map special types), but a top-level union cannot be stored as a topic schema. Nested unions inside record fields are fine; only the root union is rejected.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/validator/StructSchemaDataValidator.java:95
// This fallback is only enabled when schemaJsonAllowLegacyJacksonFormat=true (PIP-464).
try {
JSON_SCHEMA_READER.readValue(data);
} catch (IOException ioe) {
throwInvalidSchemaDataException(schemaData, ioe);
}
} else {
throwInvalidSchemaDataException(schemaData, e);
}
}
}
static void checkAvroSchemaTypeSupported(Schema schema) throws InvalidSchemaDataException {
switch (schema.getType()) {
case RECORD: {
break;
}
case UNION: {
throw new InvalidSchemaDataException(
"Avro schema typed [UNION] is not supported");
}
default: {
// INT, LONG, FLOAT, DOUBLE, BOOLEAN, STRING, BYTES.
// ARRAY, MAP, FIXED, NULL.
LOGGER.info().attr("type", schema.getType()).log("Registering a special avro schema");
}
}
}
private static void throwInvalidSchemaDataException(SchemaData schemaData,
Throwable cause) throws InvalidSchemaDataException {
throw new InvalidSchemaDataException("Invalid schema definition data for "
+ schemaData.getType() + " schema", cause);
}
static class CompatibleNameValidator implements NameValidator {
View on GitHub (pinned to 820761864e)
Solutions
- Wrap the union in a RECORD: create a top-level record with a single field whose type is the union, and register that record.
- Pick one concrete member of the union (typically the record type) and register it as the root schema.
- If nullability is the concern, model optional fields as union-typed fields INSIDE the record — nested unions are supported.
- Verify locally: new Schema.Parser().parse(json).getType() must not be Type.UNION before uploading.
Example fix
// before
String avro = "[\"null\",{\"type\":\"record\",\"name\":\"User\",\"fields\":[...]}]";
SchemaInfo info = Schema.AVRO(Schema.Parser().parse(avro)).getSchemaInfo();
// after
String avro = "{\"type\":\"record\",\"name\":\"UserRoot\",\"fields\":["
+ "{\"name\":\"user\",\"type\":[\"null\",\"User\"]}]}";
SchemaInfo info = Schema.AVRO(Schema.Parser().parse(avro)).getSchemaInfo(); Defensive patterns
Strategy: validation
Validate before calling
org.apache.avro.Schema avro = new org.apache.avro.Schema.Parser().parse(avroJson);
if (avro.getType() == org.apache.avro.Schema.Type.UNION) {
throw new IllegalArgumentException("Avro root schema must not be a UNION; wrap it in a RECORD");
} Type guard
boolean isRegisterableAvroRoot(org.apache.avro.Schema schema) {
return schema.getType() == org.apache.avro.Schema.Type.RECORD
|| schema.getType() != org.apache.avro.Schema.Type.UNION;
} Prevention
- Parse the Avro JSON and assert getType() == RECORD before uploading to the registry.
- Model nullability with unions on record fields, never as the root schema.
- When reusing Avro field schemas, take the enclosing record schema, not the field's union schema.
When it happens
Trigger: Registering an AVRO (or a KEY_VALUE whose side is AVRO) schema parsed from a JSON definition like ["null", {"type":"record",...}] or ["int","string"] — e.g. Schema.AVRO on a generic union, ReflectDatum-generated unions, or hand-written Avro JSON starting with "[".
Common situations: Avro codegen or frameworks producing optional-field root unions; devs using org.apache.avro.Schema unions to represent 'null or record'; copying an Avro field schema (union) instead of the record schema into the registry.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Incompatible schema: expected Avro schema format for SchemaT
- Incompatible schema: existing schema is not in valid Avro fo
- Incompatible schema: exists schema type %s, new schema type
- Invalid schema definition data for primitive schemas :length
- deserialize ProtobufNative Schema failed
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/e7e4f7983c7959a3.
Report an issue: GitHub.