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

  1. Verify the producer/connector plugin jar exists under the plugin/ (or standby) directory and is loadable.
  2. Confirm the SPI descriptor META-INF/canal/<fully-qualified-interface> contains a line 'name=implClass' for the requested name.
  3. 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.
  4. 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

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


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