apache/flink · error · IllegalArgumentException
get %s descriptors error!
Error message
get %s descriptors error!
What it means
PbFormatUtils.getDescriptor loads the protobuf message class via the thread-context classloader and reflectively invokes its static getDescriptor() method. Any failure (ClassNotFoundException, missing method, invocation exception, wrong type) is wrapped in this IllegalArgumentException with the class name. It is a classpath/wiring problem: the configured protobuf.message-class-name cannot be resolved to a Descriptors.Descriptor in the job's classloader.
Source
Thrown at flink-formats/flink-protobuf/src/main/java/org/apache/flink/formats/protobuf/util/PbFormatUtils.java:125
fileDescriptor.getOptions().hasJavaPackage()
? fileDescriptor.getOptions().getJavaPackage()
: fileDescriptor.getPackage();
if (fileDescriptor.getOptions().getJavaMultipleFiles()) {
return javaPackageName + ".";
} else {
String outerClassName = getOuterClassName(fileDescriptor);
return javaPackageName + "." + outerClassName + ".";
}
}
public static Descriptors.Descriptor getDescriptor(String className) {
try {
Class<?> pbClass =
Class.forName(className, true, Thread.currentThread().getContextClassLoader());
return (Descriptors.Descriptor)
pbClass.getMethod(PbConstant.PB_METHOD_GET_DESCRIPTOR).invoke(null);
} catch (Exception e) {
throw new IllegalArgumentException(
String.format("get %s descriptors error!", className), e);
}
}
public static boolean isRepeatedType(LogicalType type) {
return type instanceof MapType || type instanceof ArrayType;
}
public static boolean isArrayType(LogicalType type) {
return type instanceof ArrayType;
}
}
View on GitHub (pinned to 2f3c205e92)
Solutions
- Verify the exact FQCN: it must be the generated message class (e.g. com.example.OrderOuterClass$Order) and match 'protobuf.message-class-name'.
- Ensure the jar containing the generated classes is shipped with the job (check the fat jar contents) and not masked by lib/ conflicts.
- Regenerate proto classes with the same protoc/protobuf-java version Flink uses.
- Confirm getDescriptor() exists: javap or a quick reflection test in the job's classloader.
Example fix
-- before 'protobuf.message-class-name'='com.example.Order' -- after (nested message class) 'protobuf.message-class-name'='com.example.OrderOuterClass$Order'
Defensive patterns
Strategy: validation
Validate before calling
String cn = "com.example.OrderOuterClass$Order";
Class<?> c = Class.forName(cn, true, Thread.currentThread().getContextClassLoader());
if (c.getMethod("getDescriptor").invoke(null) instanceof Descriptors.Descriptor) {
// safe to use as protobuf.message-class-name
} Try / catch
try {
descriptor = PbFormatUtils.getDescriptor(className);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Proto class not loadable in job classloader: " + className, e);
} Prevention
- Bundle generated proto classes in the job jar and pin protoc/protobuf-java to Flink's version.
- Use the exact generated class name ($-nested for inner messages); verify with javap.
- Prefer message-class-name validation at deploy time (smoke CREATE TABLE) before production.
When it happens
Trigger: 'protobuf.message-class-name' points to a class not on the job classpath; the class exists but is not a generated protobuf message (no static getDescriptor); shaded/relocated proto classes where reflection cannot find the method; classloader isolation (planner/user classloader) hiding the proto jar.
Common situations: Proto jar not bundled in the Flink job jar; wrong fully-qualified name (old package after regenerating); proto classes compiled with a different protobuf-java version than the runtime; JAR conflicts in lib/.
Related errors
- Failed to delegate to ProtoSchemaConverter
- Bad syntax for classpath: {}
- Multiple compatible client factories found for: {}.
- No ClusterClientFactory found. If you were targeting a Yarn
- Could not load class for serialization config
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/5c65602a7c20d5c2.
Report an issue: GitHub.