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

  1. Send the schema as a valid Avro schema (e.g. via Schema.JSON(...).getSchemaInfo() on a modern client that serializes to Avro).
  2. If legacy Jackson-format clients must be supported, enable the legacy JSON schema format option on the broker (allowLegacyJacksonFormat).
  3. 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

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


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