apache/pulsar · error · SchemaSerializationException

${fileDescriptor.getFullName()} can't resolve dependency '${

Error message

${fileDescriptor.getFullName()} can't resolve dependency '${unResolvedFileDescriptNames}'.

What it means

ProtobufNativeSchemaUtils.serializeFileDescriptor caches the file descriptor's own proto and requires all its dependency descriptors to already be in the cache. If any dependency is missing it throws SchemaSerializationException naming the unresolvable dependencies.

Source

Thrown at pulsar-client/src/main/java/org/apache/pulsar/client/impl/schema/ProtobufNativeSchemaUtils.java:84

        }
        return schemaDataBytes;
    }

    private static void serializeFileDescriptor(Descriptors.FileDescriptor fileDescriptor,
                                                Map<String, FileDescriptorProto> fileDescriptorCache) {
        fileDescriptor.getDependencies().forEach(dependency -> {
                    if (!fileDescriptorCache.containsKey(dependency.getFullName())) {
                        serializeFileDescriptor(dependency, fileDescriptorCache);
                    }
                }
        );
        String[] unResolvedFileDescriptNames = fileDescriptor.getDependencies().stream().
                filter(item -> !fileDescriptorCache.containsKey(item.getFullName()))
                .map(Descriptors.FileDescriptor::getFullName).toArray(String[]::new);
        if (unResolvedFileDescriptNames.length == 0) {
            fileDescriptorCache.put(fileDescriptor.getFullName(), fileDescriptor.toProto());
        } else {
            throw new SchemaSerializationException(fileDescriptor.getFullName() + " can't resolve dependency '"
                    + Arrays.toString(unResolvedFileDescriptNames) + "'.");
        }
    }

    private static final ObjectReader PROTOBUF_NATIVE_SCHEMADATA_READER = ObjectMapperFactory.getMapper().reader()
            .forType(ProtobufNativeSchemaData.class);

    @SuppressWarnings("deprecation")
    public static Descriptors.Descriptor deserialize(byte[] schemaDataBytes) {
        Descriptors.Descriptor descriptor;
        try {
            ProtobufNativeSchemaData schemaData = PROTOBUF_NATIVE_SCHEMADATA_READER.readValue(schemaDataBytes);

            Map<String, FileDescriptorProto> fileDescriptorProtoCache = new HashMap<>();
            Map<String, Descriptors.FileDescriptor> fileDescriptorCache = new HashMap<>();
            FileDescriptorSet fileDescriptorSet = FileDescriptorSet.parseFrom(schemaData.getFileDescriptorSet());
            fileDescriptorSet.getFileList().forEach(fileDescriptorProto ->
                    fileDescriptorProtoCache.put(fileDescriptorProto.getName(), fileDescriptorProto));

View on GitHub (pinned to 820761864e)

Solutions

  1. Register dependencies first: call serializeFileDescriptor for each imported proto's FileDescriptor before the top-level one
  2. Build the FileDescriptor with the full Descriptors.FileDescriptor[] dependency array so imports are resolved
  3. Check the proto import paths and that all imported files are on the classpath and compiled

Example fix

// before
ProtobufNativeSchemaUtils.serializeFileDescriptor(topLevelFd); // imports unresolved
// after
ProtobufNativeSchemaUtils.serializeFileDescriptor(depFd);
ProtobufNativeSchemaUtils.serializeFileDescriptor(topLevelFd);
Defensive patterns

Strategy: validation

Validate before calling

List<String> missing = fd.getDependencies().stream().map(Descriptors.FileDescriptor::getFullName)
    .filter(n -> !isRegistered(n)).collect(Collectors.toList());
if (!missing.isEmpty()) { throw new IllegalStateException("register deps first: " + missing); }

Try / catch

try { serializeFileDescriptor(fd); } catch (SchemaSerializationException e) { // register listed dependencies and retry }

Prevention

When it happens

Trigger: Serializing a protobuf FileDescriptor whose proto imports other proto files whose descriptors were never registered (never passed through serializeFileDescriptor before).

Common situations: Proto files split across modules where only the top-level descriptor is registered; dependency-order mistakes when seeding the cache; dynamic proto usage where imports were not resolved at compile time.

Related errors


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