{"record":{"id":"df1e3b458e3c5a67","repo":"apache/beam","slug":"incorrect-thrift-class-provided-s","errorCode":null,"errorMessage":"Incorrect thrift class provided: %s","messagePattern":"Incorrect thrift class provided: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftPayloadSerializerProvider.java","lineNumber":52,"sourceCode":"import org.apache.thrift.TBase;\nimport org.apache.thrift.protocol.TProtocolFactory;\n\n@Internal\n@SuppressWarnings(\"rawtypes\")\n@AutoService(PayloadSerializerProvider.class)\npublic class ThriftPayloadSerializerProvider implements PayloadSerializerProvider {\n  @Override\n  public String identifier() {\n    return \"thrift\";\n  }\n\n  private static Class<? extends TBase> getMessageClass(Map<String, Object> tableParams) {\n    String thriftClassName = checkArgumentNotNull(tableParams.get(\"thriftClass\")).toString();\n    try {\n      Class<?> thriftClass = Class.forName(thriftClassName);\n      return thriftClass.asSubclass(TBase.class);\n    } catch (ClassNotFoundException e) {\n      throw new IllegalArgumentException(\"Incorrect thrift class provided: \" + thriftClassName, e);\n    }\n  }\n\n  private static TProtocolFactory getProtocolFactory(Map<String, Object> tableParams) {\n    String thriftFactoryClassName =\n        checkArgumentNotNull(tableParams.get(\"thriftProtocolFactoryClass\")).toString();\n    try {\n      Class<?> thriftClass = Class.forName(thriftFactoryClassName);\n      return thriftClass.asSubclass(TProtocolFactory.class).getDeclaredConstructor().newInstance();\n    } catch (ReflectiveOperationException e) {\n      throw new IllegalArgumentException(\n          \"Incorrect thrift protocol factory class provided: \" + thriftFactoryClassName, e);\n    }\n  }\n\n  private static void inferAndVerifySchema(Class<?> thriftClass, Schema requiredSchema) {\n    TypeDescriptor<?> typeDescriptor = TypeDescriptor.of(thriftClass);\n    Schema schema = checkArgumentNotNull(ThriftSchema.provider().schemaFor(typeDescriptor));","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/thrift/src/main/java/org/apache/beam/sdk/io/thrift/ThriftPayloadSerializerProvider.java#L34-L70","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Verify the fully-qualified class name in the thriftClass parameter (package + class, exact spelling)","Add the jar containing the generated thrift class to the pipeline classpath (--filesToStage or build dependency)","Confirm the class extends TBase (generated thrift structs do; plain POJOs do not)"],"exampleFix":"// before\nMap<String, Object> params = Map.of(\"thriftClass\", \"com.example.ThriftRecord\"); // class not staged\n// after\nMap<String, Object> params =\n    Map.of(\"thriftClass\", \"com.example.thrift.ThriftRecord\"); // correct FQCN, jar staged via --filesToStage","handlingStrategy":"validation","validationCode":"try { Class.forName(params.get(\"thriftClass\").toString()).asSubclass(TBase.class); } catch (ReflectiveOperationException e) { failFast(\"bad thriftClass param\", e); }","typeGuard":null,"tryCatchPattern":"try { io = ThriftIO.read().withParams(params); } catch (IllegalArgumentException e) { throw new IllegalStateException(\"Check thriftClass name and worker classpath\", e); }","preventionTips":["Use constants for fully-qualified class names, not inline strings","Stage generated thrift jars with --filesToStage on distributed runners","Smoke-test Class.forName in a unit test before launching pipelines"],"tags":["java","thrift","classpath","configuration"],"backgroundTag":"class-not-found","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}