alibaba/canal · error · IllegalStateException
Extension instance(name: {}, class: {}) could not be instan
Error message
Extension instance(name: {}, class: {}) could not be instantiated: class could not be found What it means
Thrown by createExtension(name, spiDir, standbyDir) when the requested name is not present in the loaded extension class map (getExtensionClasses().get(name) == null). This means no META-INF/canal/<interface> or META-INF/services/<interface> entry maps that name to a class. It is the canonical 'extension not found' error and also surfaces indirectly when a bad extension was rejected during loading (e.g. subtype/duplicate errors 215/216 that were stored, not thrown, at load time).
Source
Thrown at connector/core/src/main/java/com/alibaba/otter/canal/connector/core/spi/ExtensionLoader.java:169
return (T) instance;
}
/**
* 返回缺省的扩展,如果没有设置则返回<code>null</code>
*/
public T getDefaultExtension(String spiDir, String standbyDir) {
getExtensionClasses(spiDir, standbyDir);
if (null == cachedDefaultName || cachedDefaultName.length() == 0 || "true".equals(cachedDefaultName)) {
return null;
}
return getExtension(cachedDefaultName, spiDir, standbyDir);
}
@SuppressWarnings("unchecked")
public T createExtension(String name, String spiDir, String standbyDir) {
Class<?> clazz = getExtensionClasses(spiDir, standbyDir).get(name);
if (clazz == null) {
throw new IllegalStateException("Extension instance(name: " + name + ", class: " + type
+ ") could not be instantiated: class could not be found");
}
try {
T instance = (T) EXTENSION_INSTANCES.get(clazz);
if (instance == null) {
EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
instance = (T) EXTENSION_INSTANCES.get(clazz);
}
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance(name: " + name + ", class: " + type
+ ") could not be instantiated: " + t.getMessage(), t);
}
}
@SuppressWarnings("unchecked")
private T createExtension(String name, String key, String spiDir, String standbyDir) {
Class<?> clazz = getExtensionClasses(spiDir, standbyDir).get(name);View on GitHub (pinned to 87be50e876)
Solutions
- Verify the producer/connector plugin jar exists under the plugin/ (or standby) directory and is loadable.
- Confirm the SPI descriptor META-INF/canal/<fully-qualified-interface> contains a line 'name=implClass' for the requested name.
- Check the ExtensionLoader exceptions map / logs ('Exception when load extension class') to see if the entry was rejected during load (subtype mismatch or duplicate), and fix that root cause.
- Correct the mode name in config (e.g. 'rocketmq' not 'rocketMQ').
Example fix
# before canal.serverMode = rocketmqq # typo, no such extension # after canal.serverMode = rocketmq
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check that the name is registered before requesting
java.util.Map<String,Class<?>> known = reflectRegisteredNames(interfaceType);
if (!known.containsKey(name)) {
throw new IllegalStateException(
"extension '" + name + "' not registered; known: " + known.keySet());
}
loader.getExtension(name, spiDir, standbyDir); Try / catch
try {
return loader.getExtension(name, spiDir, standbyDir);
} catch (IllegalStateException e) {
if (e.getMessage().contains("could not be found")) {
// name not on classpath: verify plugin jar + descriptor, or fall back
throw new IllegalStateException(
"extension '" + name + "' missing: check plugin/ jar and "
+ "META-INF/canal/" + interfaceType.getName(), e);
}
throw e;
} Prevention
- Ship the connector plugin jar in plugin/ and its META-INF/canal descriptor.
- Check load-time logs for rejected entries that silently drop a name.
- Validate the mode name spelling against registered names at startup.
When it happens
Trigger: Requesting getExtension("kafka") when no 'kafka=com.alibaba...KafkaMQProducer' line exists in the SPI descriptor; the connector jar providing that implementation is not on the classpath/plugin dir; the entry exists but was rejected during load (then silently stored in the exceptions map).
Common situations: canal.serverMode/canal.mq.mode set to a producer whose plugin jar is missing from plugin/ or deployer lib; typo in the mode name; SPI descriptor file missing or in the wrong directory (META-INF/canal vs META-INF/services); extension present but failed validation at load (see ExtensionLoader loadFile exceptions map).
Related errors
- Extension instance(name: ${name}, class: ${type}) could not
- Extension name == null
- more than 1 default extension name on extension ${type.getNa
- Error when load extension class(interface: ${type}, class li
- Duplicate extension ${type.getName()} name ${n} on ${c.getNa
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/bcbafd771feec3cf.
Report an issue: GitHub.