{"record":{"id":"b7841122ebf0b1f3","repo":"apache/pulsar","slug":"invalid-schema-definition-data-for-string-schema","errorCode":null,"errorMessage":"Invalid schema definition data for string schema : '","messagePattern":"Invalid schema definition data for string schema : '","errorType":"validation","errorClass":"InvalidSchemaDataException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/validator/StringSchemaDataValidator.java","lineNumber":47,"sourceCode":"\n    public static final StringSchemaDataValidator of() {\n        return INSTANCE;\n    }\n\n    private static final StringSchemaDataValidator INSTANCE = new StringSchemaDataValidator();\n\n    private static final String PY_NONE_SCHEMA_INFO = \"null\";\n\n    private StringSchemaDataValidator() {}\n\n    @Override\n    public void validate(SchemaData schemaData) throws InvalidSchemaDataException {\n        byte[] data = schemaData.getData();\n        if (null != data && data.length > 0) {\n            // python send 'null' string as schema data\n            String schemaDataStr = new String(data, UTF_8);\n            if (!PY_NONE_SCHEMA_INFO.equals(schemaDataStr)) {\n                throw new InvalidSchemaDataException(\"Invalid schema definition data for string schema : '\"\n                    + schemaDataStr + \"'\");\n            }\n        }\n    }\n}\n","sourceCodeStart":29,"sourceCodeEnd":53,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/validator/StringSchemaDataValidator.java#L29-L53","documentation":"StringSchemaDataValidator.validate requires STRING schema definition bytes to be empty; the only tolerated non-empty value is the literal string \"null\" (Python's py None sent as schema data). Any other payload is rejected with InvalidSchemaDataException embedding the offending string. Like primitives, the STRING type carries no schema definition.","triggerScenarios":"Registering a schema with type STRING (or as part of a KEY_VALUE schema whose side is STRING) while supplying non-empty schema data other than \"null\" — e.g. SchemaInfo built with data = \"string\".getBytes() or a leftover encoding definition.","commonSituations":"Python clients historically sending b'null' (explicitly tolerated); Java tooling copying an Avro SchemaInfo and changing only the type to STRING; tests populating data with placeholder text; framework-generated info that always sets a definition.","solutions":["Set the schema data to an empty byte array for STRING schemas (or, from Python clients, \"null\" is tolerated but empty is preferred).","If you have real content, the schema isn't STRING — register as AVRO/JSON instead.","Fix the constructing code so it calls data(new byte[0]) when the type is STRING."],"exampleFix":"// before\nSchemaInfo info = SchemaInfoImpl.builder().type(SchemaType.STRING)\n    .data(\"utf8-string\".getBytes(UTF_8)).build();\n// after\nSchemaInfo info = SchemaInfoImpl.builder().type(SchemaType.STRING)\n    .data(new byte[0]).build();","handlingStrategy":"validation","validationCode":"if (info.getType() == SchemaType.STRING\n        && info.getData() != null && info.getData().length > 0\n        && !\"null\".equals(new String(info.getData(), java.nio.charset.StandardCharsets.UTF_8))) {\n    throw new IllegalArgumentException(\"STRING schema must have empty schema data\");\n}","typeGuard":"boolean validStringSchemaData(SchemaInfo info) {\n    byte[] d = info.getData();\n    return d == null || d.length == 0 || \"null\".equals(new String(d, java.nio.charset.StandardCharsets.UTF_8));\n}","tryCatchPattern":null,"preventionTips":["Use Schema.STRING instead of hand-built STRING SchemaInfo so data stays empty.","Do not reuse a structured schema's data field when switching type to STRING.","For Python clients, send an empty payload rather than b'null' when defining STRING schemas."],"tags":["pulsar","schema-validation","python"],"backgroundTag":"schema-validation-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}