apache/pulsar · error · IncompatibleSchemaException
Unknown SchemaCompatibilityStrategy.
Error message
Unknown SchemaCompatibilityStrategy.
What it means
ProtobufNativeSchemaCompatibilityCheck handles BACKWARD, FORWARD, FULL and ALWAYS_COMPATIBLE strategies; any other strategy value falls through the switch's default branch and throws, because root-message comparison semantics are undefined for it.
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/ProtobufNativeSchemaCompatibilityCheck.java:55
@Override
public void checkCompatible(SchemaData from, SchemaData to, SchemaCompatibilityStrategy strategy)
throws IncompatibleSchemaException {
Descriptor fromDescriptor = ProtobufNativeSchemaUtils.deserialize(from.getData());
Descriptor toDescriptor = ProtobufNativeSchemaUtils.deserialize(to.getData());
switch (strategy) {
case BACKWARD_TRANSITIVE:
case BACKWARD:
case FORWARD_TRANSITIVE:
case FORWARD:
case FULL_TRANSITIVE:
case FULL:
checkRootMessageChange(fromDescriptor, toDescriptor, strategy);
return;
case ALWAYS_COMPATIBLE:
return;
default:
throw new IncompatibleSchemaException("Unknown SchemaCompatibilityStrategy.");
}
}
@Override
public void checkCompatible(Iterable<SchemaData> from, SchemaData to, SchemaCompatibilityStrategy strategy)
throws IncompatibleSchemaException {
for (SchemaData schemaData : from) {
checkCompatible(schemaData, to, strategy);
}
}
private void checkRootMessageChange(Descriptor fromDescriptor, Descriptor toDescriptor,
SchemaCompatibilityStrategy strategy) throws IncompatibleSchemaException {
if (!fromDescriptor.getFullName().equals(toDescriptor.getFullName())) {
throw new IncompatibleSchemaException("Protobuf root message change is not allowed under the '"
+ strategy + "' strategy. Original message name: '" + fromDescriptor.getFullName()
+ "', new message name: '" + toDescriptor.getFullName() + "'.");
}View on GitHub (pinned to 820761864e)
Solutions
- Set the namespace/topic schema compatibility strategy to FULL, BACKWARD, FORWARD, or ALWAYS_COMPATIBLE (FULL is the safest for Protobuf Native).
- Upgrade Pulsar so the strategy set is consistent between broker components.
- Check the namespace policy with admin.namespaces().getSchemaCompatibilityStrategy() before updating Protobuf Native schemas.
Example fix
// before admin.namespaces().setSchemaCompatibilityStrategy(ns, SchemaCompatibilityStrategy.UNDEFINED); // after admin.namespaces().setSchemaCompatibilityStrategy(ns, SchemaCompatibilityStrategy.FULL);
Defensive patterns
Strategy: validation
Validate before calling
SchemaCompatibilityStrategy s = admin.namespaces().getSchemaCompatibilityStrategy(ns);
Set<SchemaCompatibilityStrategy> supported = EnumSet.of(BACKWARD, FORWARD, FULL, ALWAYS_COMPATIBLE);
if (!supported.contains(s)) throw new IllegalStateException("Unsupported strategy for Protobuf Native: " + s); Type guard
boolean protobufNativeStrategySupported(SchemaCompatibilityStrategy s) {
return s == SchemaCompatibilityStrategy.BACKWARD || s == SchemaCompatibilityStrategy.FORWARD
|| s == SchemaCompatibilityStrategy.FULL || s == SchemaCompatibilityStrategy.ALWAYS_COMPATIBLE;
} Try / catch
try {
admin.schemas().createSchema(topic, protoNativeSchemaInfo);
} catch (PulsarAdminException e) {
if (e.getMessage().contains("Unknown SchemaCompatibilityStrategy")) {
// set namespace strategy to FULL (or another supported value)
}
} Prevention
- Use FULL compatibility for Protobuf Native topics by default.
- Verify namespace strategy after any namespace policy migration.
- Keep broker versions consistent across the cluster so strategy enums match.
- Document the allowed strategy values for protobuf-native topics in team runbooks.
When it happens
Trigger: checkCompatible on a PROTOBUF_NATIVE schema with a SchemaCompatibilityStrategy other than BACKWARD/FORWARD/FULL/ALWAYS_COMPATIBLE — e.g. a strategy enum value added later (like NONE/UNDEFINED) reaching this checker.
Common situations: Namespace-level schemaCompatibilityStrategy set to a value not supported by the Protobuf Native checker; brokers with newer strategy enums interacting with older check implementations; misconfigured namespace policies.
Related errors
- Protobuf root message change is not allowed under the '%s' s
- deserialize ProtobufNative Schema failed
- protobuf root message descriptor is null, please recheck roo
- The topic has a max partition index of %d, the number of par
- entryFilterNames can't be empty. To remove entry filters use
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/903aeda542172fbe.
Report an issue: GitHub.