alibaba/canal · error · IllegalArgumentException
Extension name == null
Error message
Extension name == null
What it means
Thrown by ExtensionLoader.getExtension(name, spiDir, standbyDir) (3-arg overload) when name is null or empty. This is the entry point that resolves a named extension; a null/blank name has no meaning unless it is the literal "true" (which selects the default). It is a caller programming error.
Source
Thrown at connector/core/src/main/java/com/alibaba/otter/canal/connector/core/spi/ExtensionLoader.java:107
public ExtensionLoader(Class<?> type){
this.type = type;
this.classLoaderPolicy = DEFAULT_CLASSLOADER_POLICY;
}
public ExtensionLoader(Class<?> type, String classLoaderPolicy){
this.type = type;
this.classLoaderPolicy = classLoaderPolicy;
}
/**
* 返回指定名字的扩展
*
* @param name
* @return
*/
@SuppressWarnings("unchecked")
public T getExtension(String name, String spiDir, String standbyDir) {
if (name == null || name.length() == 0) throw new IllegalArgumentException("Extension name == null");
if ("true".equals(name)) {
return getDefaultExtension(spiDir, standbyDir);
}
Holder<Object> holder = cachedInstances.get(name);
if (holder == null) {
cachedInstances.putIfAbsent(name, new Holder<>());
holder = cachedInstances.get(name);
}
Object instance = holder.get();
if (instance == null) {
synchronized (holder) {
instance = holder.get();
if (instance == null) {
instance = createExtension(name, spiDir, standbyDir);
holder.set(instance);
}
}
}View on GitHub (pinned to 87be50e876)
Solutions
- Supply a concrete extension name registered in META-INF/canal/<interface> (e.g. "rocketmq", "kafka", "rabbitmq").
- Set the missing configuration property (canal.mq.mode / canal.serverMode) that drives the name.
- Default the name explicitly before calling getExtension if null is a valid configuration state.
Example fix
// before
String mq = properties.getProperty("canal.mq.mode"); // null
loader.getExtension(mq, spiDir, standbyDir);
// after
String mq = properties.getProperty("canal.mq.mode", "rocketmq");
loader.getExtension(mq, spiDir, standbyDir); Defensive patterns
Strategy: validation
Validate before calling
// Resolve a non-empty name (with a default) before getExtension
String name = properties.getProperty("canal.mq.mode");
if (name == null || name.trim().isEmpty()) {
name = "rocketmq"; // explicit default
}
loader.getExtension(name.trim(), spiDir, standbyDir); Try / catch
try {
loader.getExtension(name, spiDir, standbyDir);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Extension name == null")) {
// config produced empty name; supply default or fail with context
} else throw e;
} Prevention
- Always supply a default for config-driven extension names.
- Validate mode/name config at startup and fail fast with the property name.
When it happens
Trigger: Passing a null/empty extension name, e.g. reading canal.mq.mode or canal.instance.filter from config that resolved to null/blank and forwarding it to getExtension.
Common situations: Missing config property that maps to the extension name (e.g. canal.mq.mode not set); logic that computes the name returning null; whitespace-only value trimmed to empty.
Related errors
- Extension instance(name: {}, class: {}) could not be instan
- Extension instance(name: ${name}, class: ${type}) could not
- more than 1 default extension name on extension ${type.getNa
- Extension type == null
- Extension type({}) is not interface!
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/32715946638a42ec.
Report an issue: GitHub.