apache/dubbo · error · IllegalStateException
Input type ${clazz} doesn't implement Extension ${type}
Error message
Input type ${clazz} doesn't implement Extension ${type} What it means
Thrown by ExtensionLoader.replaceExtension(String name, Class<?> clazz) when the provided class does not implement the SPI interface type. This is the same assignability guard as in addExtension but for the replace path. replaceExtension is marked @Deprecated and intended for test use only.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java:693
cachedAdaptiveClass = clazz;
}
}
/**
* Replace the existing extension via API
*
* @param name extension name
* @param clazz extension class
* @throws IllegalStateException when extension to be placed doesn't exist
* @deprecated not recommended any longer, and use only when test
*/
@Deprecated
public void replaceExtension(String name, Class<?> clazz) {
checkDestroyed();
getExtensionClasses(); // load classes
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException("Input type " + clazz + " doesn't implement Extension " + type);
}
if (clazz.isInterface()) {
throw new IllegalStateException("Input type " + clazz + " can't be interface!");
}
if (!clazz.isAnnotationPresent(Adaptive.class)) {
if (StringUtils.isBlank(name)) {
throw new IllegalStateException("Extension name is blank (Extension " + type + ")!");
}
if (!cachedClasses.get().containsKey(name)) {
throw new IllegalStateException("Extension name " + name + " doesn't exist (Extension " + type + ")!");
}
cachedNames.put(clazz, name);
cachedClasses.get().put(name, clazz);
cachedInstances.remove(name);
} else {
if (cachedAdaptiveClass == null) {View on GitHub (pinned to 3a3043227f)
Solutions
- Ensure the replacement class implements the SPI interface managed by this ExtensionLoader.
- Verify you are calling replaceExtension on the correct ExtensionLoader (the right type).
- Since replaceExtension is deprecated, prefer addExtension with a unique name or SPI config files.
Example fix
// before — wrong class type
protocolLoader.replaceExtension("dubbo", WrongImpl.class);
// after
class CustomDubboProtocol implements Protocol { ... }
protocolLoader.replaceExtension("dubbo", CustomDubboProtocol.class); Defensive patterns
Strategy: type-guard
Validate before calling
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException(
clazz + " must implement " + type.getName());
}
loader.replaceExtension(name, clazz); Type guard
static boolean implementsSpi(Class<?> implClass, Class<?> spiType) {
return implClass != null && spiType != null && spiType.isAssignableFrom(implClass);
} Prevention
- Verify assignability before calling replaceExtension.
- Note that replaceExtension is deprecated — prefer SPI config files or addExtension for production code.
- Ensure the replacement class is for the correct SPI type.
When it happens
Trigger: Calling replaceExtension with a class that is not assignable to the SPI interface type. For example, replacing a Protocol extension with a class that only implements Filter. The check uses type.isAssignableFrom(clazz).
Common situations: Developer mistakenly uses the wrong ExtensionLoader instance (for a different SPI type). After refactoring, the replacement class no longer implements the required interface. Copy-paste from addExtension code without adjusting the class.
Related errors
- Input type ${clazz} doesn't implement the Extension ${type}
- Input type ${clazz} can't be interface!
- Extension name is blank (Extension {})!
- Extension name {} doesn't exist (Extension {})!
- Adaptive Extension doesn't exist (Extension {})!
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/da1d6a44f7af3437.
Report an issue: GitHub.