apache/beam · error · RuntimeException
Could not find class:
Error message
Could not find class:
What it means
resolveClass loads a deserializer/serializer/startup-modes class by name via Class.forName in the external transform configuration path. If the class is not on the classpath, the ClassNotFoundException is converted to this RuntimeException naming the class.
Solutions
- Fix the fully-qualified class name (check package and spelling).
- Add the dependency jar containing the class (e.g. io.confluent:kafka-avro-serializer) to the pipeline classpath.
- Verify with Class.forName in a quick test or `mvn dependency:tree` that the artifact is included.
Example fix
// before "KafkaAvroDeserializer" // no package, not on classpath // after "io.confluent.kafka.serializers.KafkaAvroDeserializer" + add io.confluent:kafka-avro-serializer dependency
Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(deserializerName);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Deserializer not on classpath: " + deserializerName
+ ". Add the providing dependency (e.g. io.confluent:kafka-avro-serializer).", e);
} Try / catch
try {
pipeline.apply(KafkaIO.readAllExternal(config));
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Could not find class:")) {
log.error("Missing deserializer class; verify FQCN and dependencies: {}", e.getMessage());
}
throw e;
} Prevention
- Always use fully-qualified class names in deserializer config
- Run mvn dependency:tree to confirm serialization dependencies are bundled
- Class-load check in a startup unit test before launching pipelines
When it happens
Trigger: Passing a keyDeserializer/valueDeserializer (or other class-name config field) whose class is not present at pipeline-construction time — typo in fully-qualified name, or the jar providing the class missing from the classpath.
Common situations: Using KafkaAvroDeserializer without the kafka-avro-serializer dependency; typos in class names; shaded/relocated class names after a version upgrade.
Related errors
- Could not find class
- Could not find class
- Could not instantiate class
- Failed to locate DefaultGetSize.validateSize()
- Failed to locate ProcessContinuation.stop()
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/eff40e86e3285064.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/kafka/src/main/java/org/apache/beam/sdk/io/kafka/KafkaIO.java:4141
}
} else if (!hasHeaders && row.getSchema().hasField(FIELD_HEADERS)) {
// Log warning when headers are present but Kafka client doesn't support them
LOG.warn(
"Dropping headers from Kafka record because the Kafka client version "
+ "does not support headers (requires Kafka 0.11+).");
}
return hasHeaders
? new ProducerRecord<>(topic, partition, timestamp, key, value, headers)
: new ProducerRecord<>(topic, partition, timestamp, key, value);
}
}
private static Class<?> resolveClass(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Could not find class: " + className);
}
}
}
View on GitHub (pinned to 12126d8942)