apache/pulsar · error · SchemaSerializationException
Unable to create Avro schema for class <pojo.getName()>
Error message
Unable to create Avro schema for class <pojo.getName()>
What it means
extractAvroSchema asks Avro's ReflectData (AllowNull or not) to generate a schema for the given pojo class. If Avro throws a RuntimeException while generating the schema, it is wrapped in a SchemaSerializationException with the class name. This means the class itself is not representable as an Avro schema under reflection.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/util/SchemaUtil.java:110
validateDefaults.set(savedValidateDefaults);
}
} else {
throw new RuntimeException("Schema definition must specify pojo class or schema json definition");
}
}
public static Schema extractAvroSchema(SchemaDefinition schemaDefinition, Class pojo) {
try {
return parseAvroSchema(pojo.getDeclaredField("SCHEMA$").get(null).toString());
} catch (NoSuchFieldException | IllegalAccessException | IllegalArgumentException ignored) {
ReflectData reflectData = schemaDefinition.getAlwaysAllowNull()
? new ReflectData.AllowNull()
: new ReflectData();
AvroSchema.addLogicalTypeConversions(reflectData, schemaDefinition.isJsr310ConversionEnabled(), false);
try {
return reflectData.getSchema(pojo);
} catch (RuntimeException e) {
throw new SchemaSerializationException(
"Unable to create Avro schema for class " + pojo.getName(), e);
}
}
}
}
View on GitHub (pinned to 820761864e)
Solutions
- Fix the pojo to be Avro-reflectable: public class, public no-arg constructor, fields of Avro-supported types.
- Add @AvroSchemaCompatible / use org.apache.avro.reflect annotations (@AvroIgnore, @AvroEncode) on problematic fields.
- Enable JSR310 conversion if using java.time types: SchemaDefinition.builder().withJsr310ConversionEnabled(true).
- Alternatively provide the schema as explicit JSON instead of reflection.
Example fix
// before
class Event { private Event() {} private Object payload; }
Schema<Event> s = Schema.AVRO(Event.class);
// after
class Event { public Event() {} private byte[] payload; }
Schema<Event> s = Schema.AVRO(Event.class); Defensive patterns
Strategy: validation
Validate before calling
boolean avroReflectable(Class<?> c) {
try {
c.getDeclaredConstructor().setAccessible(true);
return !c.isInterface() && !Modifier.isAbstract(c.getModifiers());
} catch (NoSuchMethodException e) {
return false; // needs public no-arg constructor
}
} Try / catch
try {
Schema<Event> s = Schema.AVRO(Event.class);
} catch (SchemaSerializationException e) {
log.error("Pojo not Avro-reflectable: " + e.getMessage(), e);
} Prevention
- Give pojos public no-arg constructors and Avro-supported field types
- Annotate un-mappable fields with @AvroIgnore
- Enable withJsr310ConversionEnabled(true) for java.time types
- Prefer generating schema JSON at build time for complex types
When it happens
Trigger: Schema.AVRO(SomePojo.class) where the pojo has unrepresentable types, is an interface/abstract class, lacks a no-arg constructor, or has fields Avro reflection cannot map (e.g. nested generics Avro cannot handle).
Common situations: Pojo with fields of unsupported types (Object, interfaces, exotic collections); nested pojo missing public no-arg constructor; nullable handling mismatch when allowNull is disabled; JSR310 types without jsr310ConversionEnabled.
Related errors
- Error during schema compatibility check with strategy ${stra
- This method is not supported
- Not implemented for ${this.getClass}
- Unknown version ${BytesSchemaVersion.of(schemaVersion)}
- Can't get accurate schema information for topic ${topicName}
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/15e7d0ad12274e2e.
Report an issue: GitHub.