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

  1. Pass a protoc-generated Message class: SchemaDefinition.<MyMsg>builder().withPojo(MyMsg.class).build()
  2. Regenerate sources with the protobuf-maven-plugin if the Message class is missing
  3. 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

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


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/bc8a72e0469ed91d. Report an issue: GitHub.