apache/beam · error · IllegalArgumentException

Incorrect thrift class provided

Error message

Incorrect thrift class provided: %s

What it means

ThriftPayloadSerializerProvider.getMessageClass loads the 'thriftClass' entry from the table parameters via Class.forName and requires it to be a subclass of TBase. If the class name cannot be found on the classpath, an IllegalArgumentException with this message is thrown.

Solutions

  1. Verify the fully-qualified class name in the thriftClass parameter (package + class, exact spelling)
  2. Add the jar containing the generated thrift class to the pipeline classpath (--filesToStage or build dependency)
  3. Confirm the class extends TBase (generated thrift structs do; plain POJOs do not)

Example fix

// before
Map<String, Object> params = Map.of("thriftClass", "com.example.ThriftRecord"); // class not staged
// after
Map<String, Object> params =
    Map.of("thriftClass", "com.example.thrift.ThriftRecord"); // correct FQCN, jar staged via --filesToStage
Defensive patterns

Strategy: validation

Validate before calling

try { Class.forName(params.get("thriftClass").toString()).asSubclass(TBase.class); } catch (ReflectiveOperationException e) { failFast("bad thriftClass param", e); }

Try / catch

try { io = ThriftIO.read().withParams(params); } catch (IllegalArgumentException e) { throw new IllegalStateException("Check thriftClass name and worker classpath", e); }

Prevention

When it happens

Trigger: Configuring a ThriftIO read/write with a thriftClass parameter naming a class that is not on the pipeline's classpath (typo, missing fat-jar dependency, wrong fully-qualified name).

Common situations: Typos in the FQCN in pipeline options; forgetting to bundle generated thrift classes in the worker jar; running on a distributed runner where the class exists locally but not on workers.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/df1e3b458e3c5a67. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftPayloadSerializerProvider.java:52

import org.apache.thrift.TBase;
import org.apache.thrift.protocol.TProtocolFactory;

@Internal
@SuppressWarnings("rawtypes")
@AutoService(PayloadSerializerProvider.class)
public class ThriftPayloadSerializerProvider implements PayloadSerializerProvider {
  @Override
  public String identifier() {
    return "thrift";
  }

  private static Class<? extends TBase> getMessageClass(Map<String, Object> tableParams) {
    String thriftClassName = checkArgumentNotNull(tableParams.get("thriftClass")).toString();
    try {
      Class<?> thriftClass = Class.forName(thriftClassName);
      return thriftClass.asSubclass(TBase.class);
    } catch (ClassNotFoundException e) {
      throw new IllegalArgumentException("Incorrect thrift class provided: " + thriftClassName, e);
    }
  }

  private static TProtocolFactory getProtocolFactory(Map<String, Object> tableParams) {
    String thriftFactoryClassName =
        checkArgumentNotNull(tableParams.get("thriftProtocolFactoryClass")).toString();
    try {
      Class<?> thriftClass = Class.forName(thriftFactoryClassName);
      return thriftClass.asSubclass(TProtocolFactory.class).getDeclaredConstructor().newInstance();
    } catch (ReflectiveOperationException e) {
      throw new IllegalArgumentException(
          "Incorrect thrift protocol factory class provided: " + thriftFactoryClassName, e);
    }
  }

  private static void inferAndVerifySchema(Class<?> thriftClass, Schema requiredSchema) {
    TypeDescriptor<?> typeDescriptor = TypeDescriptor.of(thriftClass);
    Schema schema = checkArgumentNotNull(ThriftSchema.provider().schemaFor(typeDescriptor));

View on GitHub (pinned to 12126d8942)