apache/druid · error · ParseException

Failed to instantiate Thrift class

Error message

Failed to instantiate Thrift class [%s]

What it means

toFlattenedMap() calls Class.newInstance() on the configured Thrift class; this catch branch converts InstantiationException/IllegalAccessException into a ParseException. It fires when the configured class cannot be instantiated reflectively — typically an abstract class or interface, or one without an accessible no-argument constructor — not because of bad data.

Solutions

  1. Verify the thriftClassName configured on the ThriftInput matches a class on the task classpath; a wrong or missing class yields a null/failed instantiation from getThriftClass().
  2. Rebuild/redeploy the job with the compiled Thrift-generated TBase classes included in the ingestion spec's classpath or extensions directory.
  3. Check that the thrift protocol and transport settings in the input spec are consistent with the serialized data, since deserialization failures wrapped here can also stem from TException during detectAndDeserialize.
  4. Inspect the wrapped cause (TException/IOException) in the ParseException stack trace to distinguish class-loading problems from malformed record bytes.
  5. Upgrade or align the thrift-extensions version with the thrift library version used to generate the data classes to avoid newInstance() incompatibilities.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at extensions-contrib/thrift-extensions/src/main/java/org/apache/druid/data/input/thrift/ThriftReader.java:120 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at extensions-contrib/thrift-extensions/src/main/java/org/apache/druid/data/input/thrift/ThriftReader.java:120

  {
    return Collections.singletonList(toFlattenedMap(intermediateRow));
  }

  private Map<String, Object> toFlattenedMap(byte[] bytes) throws ParseException
  {
    try {
      final Class<TBase> clazz = getThriftClass();
      final TBase tbase = clazz.newInstance();
      ThriftDeserialization.detectAndDeserialize(bytes, tbase);
      final String json = ThriftDeserialization.SERIALIZER_SIMPLE_JSON.get().toString(tbase);
      final JsonNode node = OBJECT_MAPPER.readTree(json);
      return recordFlattener.flatten(node);
    }
    catch (TException | IOException e) {
      throw new ParseException(null, e, "Failed to deserialize Thrift data");
    }
    catch (InstantiationException | IllegalAccessException e) {
      throw new ParseException(null, e, "Failed to instantiate Thrift class [%s]", thriftClassName);
    }
    catch (ClassNotFoundException e) {
      throw new ParseException(null, e, "Thrift class [%s] not found", thriftClassName);
    }
  }

  @SuppressWarnings({"unchecked", "ReturnValueIgnored"})
  private Class<TBase> getThriftClass() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException
  {
    if (thriftClass == null) {
      final Class<TBase> clazz;
      if (jarPath != null) {
        File jar = new File(jarPath);
        URLClassLoader child = new URLClassLoader(
            new URL[]{jar.toURI().toURL()},
            this.getClass().getClassLoader()
        );
        clazz = (Class<TBase>) Class.forName(thriftClassName, true, child);

View on GitHub (pinned to 9b90983fd2)