apache/pulsar · error · InvalidSchemaDataException

protobuf root message descriptor is null, please recheck roo

Error message

protobuf root message descriptor is null, please recheck rootMessageTypeName or rootFileDescriptorName conf. 

What it means

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.

Source

Thrown at pulsar-broker/src/main/java/org/apache/pulsar/broker/service/schema/validator/ProtobufNativeSchemaDataValidator.java:37

package org.apache.pulsar.broker.service.schema.validator;

import com.google.protobuf.Descriptors;
import org.apache.pulsar.broker.service.schema.exceptions.InvalidSchemaDataException;
import org.apache.pulsar.client.impl.schema.ProtobufNativeSchemaUtils;
import org.apache.pulsar.common.protocol.schema.SchemaData;

public class ProtobufNativeSchemaDataValidator implements SchemaDataValidator {

    @Override
    public void validate(SchemaData schemaData) throws InvalidSchemaDataException {
        Descriptors.Descriptor descriptor;
        try {
            descriptor = ProtobufNativeSchemaUtils.deserialize(schemaData.getData());
        } catch (Exception e) {
            throw new InvalidSchemaDataException("deserialize ProtobufNative Schema failed", e);
        }
        if (descriptor == null) {
            throw new InvalidSchemaDataException(
                    "protobuf root message descriptor is null,"
                            + " please recheck rootMessageTypeName or rootFileDescriptorName conf. ");
        }
    }

    public static ProtobufNativeSchemaDataValidator of() {
        return INSTANCE;
    }

    private static final ProtobufNativeSchemaDataValidator INSTANCE = new ProtobufNativeSchemaDataValidator();

    private ProtobufNativeSchemaDataValidator() {
    }
}

View on GitHub (pinned to 820761864e)

Solutions

  1. Set the properties correctly: info.getSchemaProperties().put("__rootMessageTypeName", "com.example.MyMsg") matching the fully qualified protobuf message name.
  2. If using ProtobufNativeSchema.of(descriptor, rootMessageTypeName), pass the exact message name from the .proto (including package prefix).
  3. Ensure the FileDescriptorSet includes the file declaring the root message, not just its dependencies.
  4. Regenerate the schema info from the current generated class so name and descriptor stay in sync.

Example fix

// before
SchemaInfo info = ProtobufNativeSchema.of(fileDescriptor) // root msg name defaults/empty
    .getSchemaInfo();
// after
SchemaInfo info = ProtobufNativeSchema.of(fileDescriptor, "com.example.Order")
    .getSchemaInfo();
Defensive patterns

Strategy: validation

Validate before calling

com.google.protobuf.Descriptors.FileDescriptor fd = com.example.MyMsg.getDescriptor();
String root = info.getSchemaProperties().getProperty("__rootMessageTypeName", "");
boolean found = fd.getMessageTypes().stream()
    .anyMatch(m -> fd.getFullName().isEmpty() || m.getFullName().equals(root));
if (!found) {
    throw new IllegalArgumentException("__rootMessageTypeName '" + root + "' not found in descriptor set");
}

Type guard

boolean hasRootMessage(SchemaInfo info) {
    String n = info.getSchemaProperties().getProperty("__rootMessageTypeName", "");
    return !n.isBlank();
}

Prevention

When it happens

Trigger: 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").

Common situations: 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.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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