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

  1. Supply a concrete extension name registered in META-INF/canal/<interface> (e.g. "rocketmq", "kafka", "rabbitmq").
  2. Set the missing configuration property (canal.mq.mode / canal.serverMode) that drives the name.
  3. 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

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


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/32715946638a42ec. Report an issue: GitHub.