apache/pulsar · error · IllegalArgumentException
com.google.protobuf.Message is not assignable from ${pojo.ge
Error message
com.google.protobuf.Message is not assignable from ${pojo.getName()} What it means
ProtobufSchema.of(SchemaDefinition) requires the POJO to be a com.google.protobuf.Message implementation; otherwise it throws IllegalArgumentException naming the offending class. It cannot derive a protobuf schema from an arbitrary class.
Source
Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/ProtobufSchema.java:109
}
public static <T extends Message> ProtobufSchema<T> of(Class<T> pojo) {
return of(pojo, new HashMap<>());
}
@SuppressWarnings("unchecked")
public static <T> ProtobufSchema ofGenericClass(Class<T> pojo, Map<String, String> properties) {
SchemaDefinition<T> schemaDefinition = SchemaDefinition.<T>builder().withPojo(pojo)
.withProperties(properties).build();
return ProtobufSchema.of(schemaDefinition);
}
@SuppressWarnings("unchecked")
public static <T> ProtobufSchema of(SchemaDefinition<T> schemaDefinition) {
Class<T> pojo = schemaDefinition.getPojo();
if (!Message.class.isAssignableFrom(pojo)) {
throw new IllegalArgumentException(Message.class.getName()
+ " is not assignable from " + pojo.getName());
}
// The application named this class, so let Avro reflect over it and over the protobuf runtime
// types avro-protobuf resolves alongside it. This has to happen before the schema is derived,
// not after: deriving it is itself a reflective resolution, which is also why there is no
// derived schema to expand from here. Encoding and decoding go through protobuf's own reader
// and writer, so the message's nested types are never resolved by Avro.
AvroTrustedClasses.trustExactly(pojo);
SchemaInfo schemaInfo = SchemaInfoImpl.builder()
.schema(createProtobufAvroSchema(schemaDefinition.getPojo()).toString().getBytes(UTF_8))
.type(SchemaType.PROTOBUF)
.name("")
.properties(schemaDefinition.getProperties())
.build();
try {View on GitHub (pinned to 820761864e)
Solutions
- Pass a protoc-generated Message class: SchemaDefinition.<MyMsg>builder().withPojo(MyMsg.class).build()
- Regenerate sources with the protobuf-maven-plugin if the Message class is missing
- Use the appropriate schema type (AVRO/JSON) for non-protobuf POJOs
Example fix
// before ProtobufSchema.of(SchemaDefinition.<Pojo>builder().withPojo(Pojo.class).build()); // Pojo not a Message // after ProtobufSchema.of(SchemaDefinition.<MyProto.MyMsg>builder().withPojo(MyProto.MyMsg.class).build());
Defensive patterns
Strategy: type-guard
Validate before calling
if (!com.google.protobuf.Message.class.isAssignableFrom(pojo)) { throw new IllegalArgumentException("ProtobufSchema requires a generated Message class"); } Type guard
boolean isProtobufMessage(Class<?> c) { return com.google.protobuf.Message.class.isAssignableFrom(c); } Try / catch
try { ProtobufSchema.of(def); } catch (IllegalArgumentException e) { /* use correct schema type for this pojo */ } Prevention
- Only pass protoc-generated Message classes
- Verify build generates protobuf sources before schema wiring
- Choose AVRO/JSON schema types for plain POJOs
When it happens
Trigger: ProtobufSchema.of(SchemaDefinition.of(PlainPojo.class)) where PlainPojo is not generated by protoc; passing an Avro or JSON POJO by mistake.
Common situations: Reusing a SchemaDefinition built for AVRO/JSON with ProtobufSchema; forgetting to run protoc/maven plugin so the Message class doesn't exist; classpath containing a stub with the same name.
Related errors
- com.google.protobuf.Message is not assignable from ${pojo.ge
- Retrieve schema instance from schema info for type '${schema
- The input schema is not of type 'org.apache.avro.Schema'.
- ${fileDescriptor.getFullName()} can't resolve dependency '${
- '${fileDescriptorProto.getName()}' can't resolve dependency
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/bc8a72e0469ed91d.
Report an issue: GitHub.