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
- Use a TProtocolFactory implementation with a public no-arg constructor, e.g. org.apache.thrift.protocol.TBinaryProtocol$Factory or TCompactProtocol$Factory
- Make sure you reference the nested Factory class, not the protocol class itself
- 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
- Reference the $Factory nested class, never the protocol class itself
- Keep allowed factory names in an enum/constant list
- Verify the factory jar is bundled for workers
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
- Failed to construct instance of configuration class
- Incorrect thrift class provided
- No suitable static factory method
- Overloaded factory methods
- The parameter list: does not match the expected fields
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)