{"record":{"id":"d6fdc752e1e6825b","repo":"apache/druid","slug":"invalid-wrapper-type","errorCode":null,"errorMessage":"Invalid Wrapper type.","messagePattern":"Invalid Wrapper type\\.","errorType":"exception","errorClass":"InvalidProtocolBufferException","httpStatus":null,"severity":"error","filePath":"extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/ProtobufConverter.java","lineNumber":163,"sourceCode":"          return ((Descriptors.EnumValueDescriptor) value).getName();\n        }\n      case MESSAGE:\n      case GROUP:\n        return convertMessage((Message) value);\n      default:\n        // pass through everything else\n        return value;\n    }\n  }\n\n  private static Map<String, SpecializedConverter> buildSpecializedConversions()\n  {\n    final Map<String, SpecializedConverter> converters = new HashMap<>();\n    final SpecializedConverter parappaTheWrappa = msg -> {\n      final Descriptors.Descriptor descriptor = msg.getDescriptorForType();\n      final Descriptors.FieldDescriptor valueField = descriptor.findFieldByName(\"value\");\n      if (valueField == null) {\n        throw new InvalidProtocolBufferException(\"Invalid Wrapper type.\");\n      }\n      return convertSingleValue(valueField, msg.getField(valueField));\n    };\n    converters.put(BoolValue.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(Int32Value.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(UInt32Value.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(Int64Value.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(UInt64Value.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(StringValue.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(BytesValue.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(FloatValue.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(DoubleValue.getDescriptor().getFullName(), parappaTheWrappa);\n    converters.put(\n        Any.getDescriptor().getFullName(),\n        msg -> JsonFormat.printer().print(msg) // meh\n    );\n    converters.put(\n        Timestamp.getDescriptor().getFullName(),","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/protobuf-extensions/src/main/java/org/apache/druid/data/input/protobuf/ProtobufConverter.java#L145-L181","documentation":"During protobuf message conversion Druid looks up a specialized converter for google.protobuf wrapper types (BoolValue, Int32Value, etc.). The converter expects the well-known wrapper message shape with a single 'value' field. When the descriptor of the message registered as a wrapper type has no 'value' field, this InvalidProtocolBufferException is thrown, indicating the runtime descriptor does not match the expected well-known type layout.","triggerScenarios":"A field whose descriptor full name matches a registered wrapper type (e.g. google.protobuf.StringValue) is encountered during convertMessage, but its descriptor lacks a field named 'value' — practically only when a custom/older protobuf runtime provides different well-known type descriptors or the message descriptor was shadowed.","commonSituations":"Mismatched or shaded protobuf-runtime versions on the classpath (e.g. an old com.google.protobuf jar bundled by an extension or a fat jar) where well-known type descriptors differ; custom descriptor pools where a message reuses a google.protobuf.* full name.","solutions":["Check the classpath for duplicate/mismatched com.google.protobuf:protobuf-java versions (mvn dependency:tree) and align them with the version Druid's protobuf-extensions uses","Ensure no custom descriptor pool registers messages with google.protobuf.* full names that shadow the real well-known types","Upgrade the protobuf-extensions / protobuf-java to matching versions and redeploy the extension"],"exampleFix":"// before: mixed protobuf versions on classpath\nprotobuf-java 3.7.x shaded inside a custom extension jar\n// after: single aligned version in the extension pom\n<dependency>\n  <groupId>com.google.protobuf</groupId>\n  <artifactId>protobuf-java</artifactId>\n  <version>3.25.1</version>\n</dependency>","handlingStrategy":"validation","validationCode":"Descriptors.Descriptor d = msg.getDescriptorForType();\nif (\"google.protobuf.BoolValue\".equals(d.getFullName()) && d.findFieldByName(\"value\") == null) {\n  throw new IllegalStateException(\"Descriptor for \" + d.getFullName() + \" lacks 'value' field; check protobuf-java version on classpath\");\n}","typeGuard":"boolean isValidWrapper(Message msg) {\n  return msg.getDescriptorForType().findFieldByName(\"value\") != null;\n}","tryCatchPattern":"try {\n  Map<String, Object> row = ProtobufConverter.convertMessage(msg);\n} catch (InvalidProtocolBufferException e) {\n  if (e.getMessage().contains(\"Invalid Wrapper type\")) {\n    log.error(\"Wrapper descriptor mismatch — check protobuf-java versions\", e);\n  }\n  throw e;\n}","preventionTips":["Run mvn dependency:tree and enforce a single protobuf-java version with maven-enforcer banDuplicateClasses","Avoid bundling/shading protobuf-java inside Druid extensions (mark it provided)","Don't register custom descriptors using google.protobuf.* full names"],"tags":["protobuf","deserialization","classloading"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}