{"record":{"id":"79e0805cb5bad189","repo":"apache/pulsar","slug":"protobuf-root-message-descriptor-is-null-please-r","errorCode":null,"errorMessage":"protobuf root message descriptor is null, please recheck rootMessageTypeName or rootFileDescriptorName conf. ","messagePattern":"protobuf root message descriptor is null, please recheck rootMessageTypeName or rootFileDescriptorName conf\\. ","errorType":"validation","errorClass":"InvalidSchemaDataException","httpStatus":null,"severity":"error","filePath":"pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/validator/ProtobufNativeSchemaDataValidator.java","lineNumber":37,"sourceCode":"package org.apache.pulsar.broker.service.schema.validator;\n\nimport com.google.protobuf.Descriptors;\nimport org.apache.pulsar.broker.service.schema.exceptions.InvalidSchemaDataException;\nimport org.apache.pulsar.client.impl.schema.ProtobufNativeSchemaUtils;\nimport org.apache.pulsar.common.protocol.schema.SchemaData;\n\npublic class ProtobufNativeSchemaDataValidator implements SchemaDataValidator {\n\n    @Override\n    public void validate(SchemaData schemaData) throws InvalidSchemaDataException {\n        Descriptors.Descriptor descriptor;\n        try {\n            descriptor = ProtobufNativeSchemaUtils.deserialize(schemaData.getData());\n        } catch (Exception e) {\n            throw new InvalidSchemaDataException(\"deserialize ProtobufNative Schema failed\", e);\n        }\n        if (descriptor == null) {\n            throw new InvalidSchemaDataException(\n                    \"protobuf root message descriptor is null,\"\n                            + \" please recheck rootMessageTypeName or rootFileDescriptorName conf. \");\n        }\n    }\n\n    public static ProtobufNativeSchemaDataValidator of() {\n        return INSTANCE;\n    }\n\n    private static final ProtobufNativeSchemaDataValidator INSTANCE = new ProtobufNativeSchemaDataValidator();\n\n    private ProtobufNativeSchemaDataValidator() {\n    }\n}\n","sourceCodeStart":19,"sourceCodeEnd":52,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/validator/ProtobufNativeSchemaDataValidator.java#L19-L52","documentation":"After a successful FileDescriptorSet parse, the validator checks that a root message descriptor could actually be resolved; a null descriptor means the descriptor set parsed but no message matched the configured rootMessageTypeName/rootFileDescriptorName. The schema is rejected because protobuf-native schemas must be anchored to a root message type.","triggerScenarios":"Registering PROTOBUF_NATIVE schema data whose FileDescriptorSet does not contain a message named by rootMessageTypeName (schemaProperties key \"__rootMessageTypeName\") or whose file name does not match rootFileDescriptorName (\"__rootFileDescriptorName\").","commonSituations":"Typo in the root message name (case-sensitive, package-qualified name mismatches); registering a descriptor set that only contains dependencies but not the root message; building SchemaInfo from a dependency-only descriptor; renaming the proto message after schema registration without updating rootMessageTypeName.","solutions":["Set the properties correctly: info.getSchemaProperties().put(\"__rootMessageTypeName\", \"com.example.MyMsg\") matching the fully qualified protobuf message name.","If using ProtobufNativeSchema.of(descriptor, rootMessageTypeName), pass the exact message name from the .proto (including package prefix).","Ensure the FileDescriptorSet includes the file declaring the root message, not just its dependencies.","Regenerate the schema info from the current generated class so name and descriptor stay in sync."],"exampleFix":"// before\nSchemaInfo info = ProtobufNativeSchema.of(fileDescriptor) // root msg name defaults/empty\n    .getSchemaInfo();\n// after\nSchemaInfo info = ProtobufNativeSchema.of(fileDescriptor, \"com.example.Order\")\n    .getSchemaInfo();","handlingStrategy":"validation","validationCode":"com.google.protobuf.Descriptors.FileDescriptor fd = com.example.MyMsg.getDescriptor();\nString root = info.getSchemaProperties().getProperty(\"__rootMessageTypeName\", \"\");\nboolean found = fd.getMessageTypes().stream()\n    .anyMatch(m -> fd.getFullName().isEmpty() || m.getFullName().equals(root));\nif (!found) {\n    throw new IllegalArgumentException(\"__rootMessageTypeName '\" + root + \"' not found in descriptor set\");\n}","typeGuard":"boolean hasRootMessage(SchemaInfo info) {\n    String n = info.getSchemaProperties().getProperty(\"__rootMessageTypeName\", \"\");\n    return !n.isBlank();\n}","tryCatchPattern":null,"preventionTips":["Pass the fully qualified message name (package.MessageName) as rootMessageTypeName; names are case-sensitive.","Generate schema info from the current generated proto class so descriptor and root name stay in sync.","After renaming proto messages, regenerate and re-verify rootMessageTypeName before re-registering."],"tags":["pulsar","protobuf","schema-validation"],"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-14T05:17:10.506Z"}