apache/pulsar · error · IncompatibleSchemaException
Incompatible schema: expected Avro schema format for SchemaT
Error message
Incompatible schema: expected Avro schema format for SchemaType.JSON
What it means
JsonSchemaCompatibilityCheck requires JSON schemas to be stored in Avro format. This error is thrown in the checkCompatible(Iterable, SchemaData, strategy) path when the existing broker schema is Avro-formatted JSON, but the incoming schema is neither a valid Avro schema nor a legacy Jackson JsonSchema (or the legacy format is disabled).
Source
Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/JsonSchemaCompatibilityCheck.java:65
* Set whether to allow legacy Jackson JsonSchema format for backward compatibility.
* When false (default), only valid Avro schema format is accepted (PIP-464).
*/
public void setAllowLegacyJacksonFormat(boolean allowLegacyJacksonFormat) {
this.allowLegacyJacksonFormat = allowLegacyJacksonFormat;
}
@Override
public void checkCompatible(SchemaData from, SchemaData to, SchemaCompatibilityStrategy strategy)
throws IncompatibleSchemaException {
if (isAvroSchema(from)) {
if (isAvroSchema(to)) {
// if both producer and broker have the schema in avro format
super.checkCompatible(from, to, strategy);
} else if (allowLegacyJacksonFormat && isJsonSchema(to)) {
// if broker have the schema in avro format but producer sent a schema in the old json format
// allow old schema format for backwards compatibility (only when legacy format is enabled)
} else {
throw new IncompatibleSchemaException(
"Incompatible schema: expected Avro schema format for SchemaType.JSON");
}
} else if (allowLegacyJacksonFormat && isJsonSchema(from)) {
if (isAvroSchema(to)) {
// if broker have the schema in old json format but producer sent a schema in the avro format
// return true and overwrite the old format
} else if (isJsonSchema(to)) {
// if both producer and broker have the schema in old json format
isCompatibleJsonSchema(from, to);
} else {
throw new IncompatibleSchemaException(
"Incompatible schema: expected Avro schema format for SchemaType.JSON");
}
} else if (!allowLegacyJacksonFormat && !isAvroSchema(from)) {
// When legacy format is disabled, the existing schema must be valid Avro.
// If it's not, this is a defense-in-depth rejection (PIP-464).
throw new IncompatibleSchemaException(View on GitHub (pinned to 820761864e)
Solutions
- Send the schema as a valid Avro schema (e.g. via Schema.JSON(...).getSchemaInfo() on a modern client that serializes to Avro).
- If legacy Jackson-format clients must be supported, enable the legacy JSON schema format option on the broker (allowLegacyJacksonFormat).
- Validate the schema payload parses as Avro before uploading.
Example fix
// before: legacy Jackson JSON schema on Avro-only broker SchemaInfo info = SchemaInfoImpl.builder().schema(jsonBytesOfJacksonSchema).type(SchemaType.JSON)...; // after: Avro-encoded JSON schema SchemaInfo info = Schema.JSON(Pojo.class).getSchemaInfo();
Defensive patterns
Strategy: validation
Validate before calling
try (Schema.Parser p = new Schema.Parser()) {
p.parse(new String(schemaBytes, StandardCharsets.UTF_8)); // throws if not Avro
}
// or verify JsonSchema legacy shape only if allowLegacyJacksonFormat is enabled Type guard
boolean isAvroJsonSchema(byte[] data) {
try { new org.apache.avro.Schema.Parser().parse(new String(data, java.nio.charset.StandardCharsets.UTF_8)); return true; }
catch (Exception e) { return false; }
} Try / catch
try {
admin.schemas().createSchema(topic, schemaInfo);
} catch (PulsarAdminException e) {
if (e.getMessage().contains("expected Avro schema format for SchemaType.JSON")) {
schemaInfo = Schema.JSON(MyPojo.class).getSchemaInfo(); // regenerate in Avro format
}
} Prevention
- Use Schema.JSON(Pojo.class) from a current Pulsar client so schema payloads are Avro-encoded.
- Do not hand-write JSON schema definition bytes.
- Plan the migration window where allowLegacyJacksonFormat is still enabled before disabling it.
- Test schema uploads in a staging namespace before production.
When it happens
Trigger: Updating a topic schema where the stored schema is an Avro-format JSON schema and the new uploaded schema fails both isAvroSchema(to) and (allowLegacyJacksonFormat && isJsonSchema(to)).
Common situations: A producer built against an old Pulsar client sends the legacy Jackson JSON schema representation to a broker where allowLegacyJacksonFormat is false or the payload is simply malformed; or a hand-edited schema JSON string is uploaded that is neither valid Avro nor a valid JsonSchema document.
Related errors
- Incompatible schema: existing schema is not in valid Avro fo
- Incompatible Schema from %s + to %s
- Incompatible schema: exists schema type %s, new schema type
- Avro schema typed [UNION] is not supported
- Avro Record Builder doesn't support non-avro record as a fie
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/536d15bc3288baa4.
Report an issue: GitHub.