apache/beam · error · IllegalArgumentException

Unable to resolve class %s to use as Debezium connector.

Error message

Unable to resolve class %s to use as Debezium connector.

What it means

Connectors.getConnector() reflectively loads the configured Debezium connector class by fully-qualified name via Class.forName. If the name is misspelled or the connector artifact is not on the classpath, it throws IllegalArgumentException. Note the catch also handles ClassCastException from the unchecked cast.

Source

Thrown at sdks/java/io/debezium/src/main/java/org/apache/beam/io/debezium/Connectors.java:50

  private final String connector;

  Connectors(String name, String connector) {
    this.name = name;
    this.connector = connector;
  }

  /** The name of this connector class. */
  public String getName() {
    return name;
  }

  /** Class connector to debezium. */
  public @NonNull Class<? extends SourceConnector> getConnector() {
    Class<? extends SourceConnector> connectorClass = null;
    try {
      connectorClass = (Class<? extends SourceConnector>) Class.forName(this.connector);
    } catch (ClassCastException | ClassNotFoundException e) {
      throw new IllegalArgumentException(
          String.format(
              "Unable to resolve class %s to use as Debezium connector.", this.connector));
    }
    return connectorClass;
  }

  /**
   * Returns a connector class corresponding to the given connector name.
   *
   * @param connectorName The name of the connector. Ex.: MySQL
   * @return Connector enum representing the given connector name.
   */
  public static Connectors fromName(String connectorName) {
    for (Connectors connector : Connectors.values()) {
      if (connector.getName().equals(connectorName)) {
        return connector;
      }
    }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Verify the fully-qualified class name (e.g. io.debezium.connector.mysql.MySqlConnector) is spelled exactly.
  2. Add the corresponding Debezium connector artifact to the build and ensure it is shaded/bundled into the job jar.
  3. Confirm the class extends org.apache.kafka.connect.source.SourceConnector, matching your Kafka Connect API version.
  4. Test Class.forName(name) locally in the same classpath as the pipeline.

Example fix

// before
.withConnector("io.debezium.connector.mysql.MySQLConnector") // wrong case -> ClassNotFoundException
// after
.withConnector("io.debezium.connector.mysql.MySqlConnector")
// and in build.gradle: implementation 'io.debezium:debezium-connector-mysql:2.x'
Defensive patterns

Strategy: validation

Validate before calling

try {
  Class.forName("io.debezium.connector.mysql.MySqlConnector", false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
  throw new IllegalStateException("Debezium connector class missing from classpath: add the connector artifact");
}

Type guard

static boolean validConnectorName(String name) {
  return name != null && name.startsWith("io.debezium.connector.") && name.endsWith("Connector");
}

Prevention

When it happens

Trigger: Passing a connector class name (e.g. via 'connector.class' config) that does not exist on the classpath or is not a subclass of org.apache.kafka.connect.source.SourceConnector.

Common situations: Typos in the fully-qualified class name, forgetting to bundle the Debezium connector dependency (e.g. debezium-mysql-connector) into the pipeline jar, or using a class that implements a different Connector interface version.

Related errors


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