{"record":{"id":"2f78ae40d6d362ca","repo":"apache/pulsar","slug":"external-schema-is-not-compatible-with-the-other-s","errorCode":null,"errorMessage":"External schema is not compatible with the other schema types.","messagePattern":"External schema is not compatible with the other schema types\\.","errorType":"exception","errorClass":"IncompatibleSchemaException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/ExternalSchemaCompatibilityCheck.java","lineNumber":38,"sourceCode":"\nimport org.apache.pulsar.broker.service.schema.exceptions.IncompatibleSchemaException;\nimport org.apache.pulsar.common.policies.data.SchemaCompatibilityStrategy;\nimport org.apache.pulsar.common.protocol.schema.SchemaData;\nimport org.apache.pulsar.common.schema.SchemaType;\n\npublic class ExternalSchemaCompatibilityCheck implements SchemaCompatibilityCheck {\n\n    @Override\n    public SchemaType getSchemaType() {\n        return SchemaType.EXTERNAL;\n    }\n\n    @Override\n    public void checkCompatible(SchemaData from, SchemaData to, SchemaCompatibilityStrategy strategy)\n            throws IncompatibleSchemaException {\n        if ((SchemaType.EXTERNAL.equals(from.getType()) || SchemaType.EXTERNAL.equals(to.getType()))\n                && !from.getType().equals(to.getType())) {\n            throw new IncompatibleSchemaException(\"External schema is not compatible with the other schema types.\");\n        }\n    }\n\n    @Override\n    public void checkCompatible(Iterable<SchemaData> from, SchemaData to, SchemaCompatibilityStrategy strategy)\n            throws IncompatibleSchemaException {\n        for (SchemaData fromSchema : from) {\n            checkCompatible(fromSchema, to, strategy);\n        }\n    }\n\n}\n","sourceCodeStart":20,"sourceCodeEnd":51,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/ExternalSchemaCompatibilityCheck.java#L20-L51","documentation":"The ExternalSchemaCompatibilityCheck rejects any compatibility comparison where exactly one of the two schemas (existing 'from' or new 'to') has SchemaType.EXTERNAL. An EXTERNAL schema carries data managed outside Pulsar's schema registry, so it can only be compared against another EXTERNAL schema; mixing it with AVRO, JSON, etc. is meaningless to the broker.","triggerScenarios":"Calling schemaRegistryManager/SchemaRegistryService.checkCompatible (directly or via updating a topic schema) when the existing stored schema is EXTERNAL and the new schema is not EXTERNAL, or vice versa, regardless of the SchemaCompatibilityStrategy.","commonSituations":"A topic previously configured with an external schema provider (e.g. via a custom SchemaData with type EXTERNAL) is updated with a normal AVRO/JSON schema; or a script uploads an EXTERNAL-type schema onto a topic that already has a standard schema; mixed client SDK versions posting different schema types to the same topic.","solutions":["Make the new schema use the same SchemaType as the existing one — if the topic has an EXTERNAL schema, submit the update as EXTERNAL too.","If the topic should use a standard schema, delete the topic's schema first, then upload the new schema.","Audit the producer/consumer code so all clients agree on one schema type for the topic."],"exampleFix":"// before: mixed types rejected\nSchemaData from = SchemaDataImpl.builder().type(SchemaType.EXTERNAL)...;\nSchemaData to = SchemaDataImpl.builder().type(SchemaType.AVRO)...;\ncheck.checkCompatible(from, to, strategy);\n// after: both sides same type\nSchemaData to = SchemaDataImpl.builder().type(SchemaType.EXTERNAL)...;\ncheck.checkCompatible(from, to, strategy);","handlingStrategy":"validation","validationCode":"if ((existing.getType() == SchemaType.EXTERNAL) != (incoming.getType() == SchemaType.EXTERNAL)) {\n    throw new IllegalArgumentException(\"Cannot mix EXTERNAL schema with other schema types for this topic\");\n}\n// proceed with update only when types agree","typeGuard":"boolean bothExternalOrNeither(SchemaData a, SchemaData b) {\n    return a.getType() == SchemaType.EXTERNAL == (b.getType() == SchemaType.EXTERNAL);\n}","tryCatchPattern":"try {\n    admin.schemas().createSchema(topic, schemaInfo);\n} catch (PulsarAdminException e) {\n    if (e.getMessage().contains(\"External schema is not compatible\")) {\n        // fix schema type or delete existing schema first\n    }\n}","preventionTips":["Before updating a schema, fetch the current schema via admin.schemas() and compare SchemaType.","Keep EXTERNAL-schema topics dedicated to the external provider pipeline.","Never hardcode schema types per client; use a shared schema definition module.","Delete the existing schema before intentionally switching schema types."],"tags":["pulsar","schema","compatibility"],"backgroundTag":"incompatible-schema-type","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}