alibaba/canal · error · IllegalStateException
Extension instance(name: ${name}, class: ${type}) could not
Error message
Extension instance(name: ${name}, class: ${type}) could not be instantiated: ${t.getMessage()} What it means
Thrown by the private 4-arg createExtension(name, key,...) when the keyed instance cannot be instantiated — clazz.newInstance() threw. Same as 210 but on the per-key path (instance stored under EXTENSION_KEY_INSTANCE keyed by name+key).
Source
Thrown at connector/core/src/main/java/com/alibaba/otter/canal/connector/core/spi/ExtensionLoader.java:200
}
}
@SuppressWarnings("unchecked")
private T createExtension(String name, String key, 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_KEY_INSTANCE.get(name + "-" + key);
if (instance == null) {
EXTENSION_KEY_INSTANCE.putIfAbsent(name + "-" + key, clazz.newInstance());
instance = (T) EXTENSION_KEY_INSTANCE.get(name + "-" + key);
}
return instance;
} catch (Throwable t) {
throw new IllegalStateException("Extension instance(name: " + name + ", class: " + type
+ ") could not be instantiated: " + t.getMessage(), t);
}
}
private Map<String, Class<?>> getExtensionClasses(String spiDir, String standbyDir) {
Map<String, Class<?>> classes = cachedClasses.get();
if (classes == null) {
synchronized (cachedClasses) {
classes = cachedClasses.get();
if (classes == null) {
classes = loadExtensionClasses(spiDir, standbyDir);
cachedClasses.set(classes);
}
}
}
return classes;
}View on GitHub (pinned to 87be50e876)
Solutions
- Add a public no-arg constructor to the implementation.
- Move per-key init out of the constructor into an init(key) method invoked after instantiation.
- Read the wrapped cause to identify the underlying instantiation error and fix it.
Example fix
// before
public MyProducer(String key) { this.key = key; }
// after
public MyProducer() { }
public void init(String key) { this.key = key; } Defensive patterns
Strategy: try-catch
Validate before calling
// Validate keyed impl instantiability
Class<?> impl = resolveImplClass(interfaceType, name);
try { if (impl != null) impl.getConstructor(); }
catch (NoSuchMethodException e) {
throw new IllegalStateException(impl + " needs a public no-arg constructor for keyed SPI");
} Type guard
boolean isInstantiableSpi(Class<?> impl) {
try {
return impl != null && !Modifier.isAbstract(impl.getModifiers())
&& impl.getConstructor() != null;
} catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
return loader.getExtension(name, key, spiDir, standbyDir);
} catch (IllegalStateException e) {
if (e.getMessage().contains("could not be instantiated")) {
Throwable c = e.getCause();
// ensure public no-arg ctor; move per-key init out of constructor
}
throw e;
} Prevention
- Ensure keyed implementations have a public no-arg constructor.
- Bind per-key state via an init(key) method, not the constructor.
When it happens
Trigger: The implementation class for a keyed extension has no public no-arg constructor or its constructor threw; abstract class; access restriction.
Common situations: Custom per-key extension whose constructor fails; constructor depends on per-key config not yet bound; obfuscation/security constraints.
Related errors
- Extension instance(name: {}, class: {}) could not be instan
- Extension type == null
- Extension type({}) is not interface!
- Extension type({}) is not extension, because WITHOUT @{} Ann
- Extension name == null
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/3b5ed26562d447e5.
Report an issue: GitHub.