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
- Verify only one protobuf-java version is on the classpath and it matches the one used by the protobuf-extensions module
- Re-check the schema stored in the schema registry for the message; re-register the correct .proto if it shadows google.protobuf.Struct
- 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
- Keep exactly one protobuf-java version on the Druid classpath
- Validate stored schemas in the registry periodically against well-known types
- Never name custom messages with google.protobuf.* full names
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
- Invalid Wrapper type.
- Invalid Value type.
- Invalid ListValue type.
- Protobuf message could not be parsed
- Fail to decode protobuf message!
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/57b82e3a4cad8136.
Report an issue: GitHub.