apache/beam · error · IllegalArgumentException

Incorrect thrift protocol factory class provided

Error message

Incorrect thrift protocol factory class provided: %s

What it means

ThriftPayloadSerializerProvider.getProtocolFactory loads the 'thriftProtocolFactoryClass' parameter via reflection and instantiates it with a no-arg constructor. Any ReflectiveOperationException (class not found, not a TProtocolFactory, missing/inaccessible constructor) becomes an IllegalArgumentException with this message.

Solutions

  1. Use a TProtocolFactory implementation with a public no-arg constructor, e.g. org.apache.thrift.protocol.TBinaryProtocol$Factory or TCompactProtocol$Factory
  2. Make sure you reference the nested Factory class, not the protocol class itself
  3. Stage the dependency jar on workers so Class.forName succeeds on every node

Example fix

// before
params.put("thriftProtocolFactoryClass", "org.apache.thrift.protocol.TBinaryProtocol"); // not a factory
// after
params.put("thriftProtocolFactoryClass", "org.apache.thrift.protocol.TBinaryProtocol$Factory");
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = Class.forName(factoryName); if (!TProtocolFactory.class.isAssignableFrom(c)) { throw new IllegalArgumentException(factoryName + " is not a TProtocolFactory"); } c.getDeclaredConstructor();

Try / catch

try { io = ThriftIO.read().withParams(params); } catch (IllegalArgumentException e) { throw new IllegalStateException("Check thriftProtocolFactoryClass (must be a TProtocolFactory with no-arg ctor)", e); }

Prevention

When it happens

Trigger: Passing a thriftProtocolFactoryClass that doesn't exist on the classpath, names a class that doesn't implement TProtocolFactory, or has no public no-arg constructor.

Common situations: Typo like 'TBinaryProtocol$Factory' mis-spelled; passing the protocol class (TBinaryProtocol) instead of its Factory; class present locally but missing on worker nodes.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

  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));
    if (!schema.assignableTo(requiredSchema)) {
      throw new IllegalArgumentException(
          String.format(
              "Given message schema: '%s'%n"
                  + "does not match schema inferred from thrift class.%n"
                  + "Thrift class: '%s'%n"
                  + "Inferred schema: '%s'",
              requiredSchema, thriftClass.getName(), schema));
    }
  }

View on GitHub (pinned to 12126d8942)