apache/druid · error · InvalidProtocolBufferException

Invalid Struct type.

Error message

Invalid Struct type.

What it means

Druid registers a specialized converter for google.protobuf.Struct that reads its 'fields' map field. If the descriptor for the message named google.protobuf.Struct has no 'fields' field, the converter throws this InvalidProtocolBufferException because the runtime descriptor deviates from the well-known Struct definition.

Source

Thrown at extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/ProtobufConverter.java:204

    );
    converters.put(
        Duration.getDescriptor().getFullName(),
        msg -> {
          final Duration duration = Duration.parseFrom(msg.toByteString());
          return Durations.toString(duration);
        }
    );
    converters.put(
        FieldMask.getDescriptor().getFullName(),
        msg -> FieldMaskUtil.toJsonString(FieldMask.parseFrom(msg.toByteString()))
    );
    converters.put(
        Struct.getDescriptor().getFullName(),
        msg -> {
          final Descriptors.Descriptor descriptor = msg.getDescriptorForType();
          final Descriptors.FieldDescriptor field = descriptor.findFieldByName("fields");
          if (field == null) {
            throw new InvalidProtocolBufferException("Invalid Struct type.");
          }
          // Struct is formatted as a map object.
          return convertSingleValue(field, msg.getField(field));
        }
    );
    converters.put(
        Value.getDescriptor().getFullName(),
        msg -> {
          final Map<Descriptors.FieldDescriptor, Object> fields = msg.getAllFields();
          if (fields.isEmpty()) {
            return null;
          }
          if (fields.size() != 1) {
            throw new InvalidProtocolBufferException("Invalid Value type.");
          }
          final Map.Entry<Descriptors.FieldDescriptor, Object> entry = fields.entrySet().stream().findFirst().get();
          return convertSingleValue(entry.getKey(), entry.getValue());
        }

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Verify only one protobuf-java version is on the classpath and it matches the one used by the protobuf-extensions module
  2. Re-check the schema stored in the schema registry for the message; re-register the correct .proto if it shadows google.protobuf.Struct
  3. Restart Druid processes after fixing dependencies so descriptors are reloaded

Example fix

// before: custom .proto message accidentally named google.protobuf.Struct
// after: use your own package/name for the message
message MyStruct { map<string, Value> fields = 1; }
Defensive patterns

Strategy: validation

Validate before calling

Descriptors.Descriptor d = msg.getDescriptorForType();
if ("google.protobuf.Struct".equals(d.getFullName()) && d.findFieldByName("fields") == null) {
  throw new IllegalStateException("google.protobuf.Struct descriptor missing 'fields'; descriptor pool is wrong");
}

Type guard

boolean isValidStruct(Message msg) {
  return "google.protobuf.Struct".equals(msg.getDescriptorForType().getFullName())
      && msg.getDescriptorForType().findFieldByName("fields") != null;
}

Try / catch

try {
  Map<String, Object> row = ProtobufConverter.convertMessage(msg);
} catch (InvalidProtocolBufferException e) {
  if (e.getMessage().contains("Invalid Struct type")) {
    log.error("Struct descriptor mismatch — verify schema registry schema", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: convertField encounters a Message whose descriptor full name is google.protobuf.Struct but descriptor.findFieldByName("fields") returns null — i.e. a non-conformant descriptor with that well-known name at conversion time.

Common situations: Shaded or outdated protobuf-java on the classpath altering well-known type descriptors; a custom schema registered under the google.protobuf.Struct full name; corrupted schema registry metadata producing a mismatched descriptor.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/57b82e3a4cad8136. Report an issue: GitHub.