apache/dubbo · error · IllegalStateException
Error occurred when loading extension class (interface: {},
Error message
Error occurred when loading extension class (interface: {}, class line: {}), class {} is not subtype of interface. What it means
Thrown by loadClass() when a class declared in a META-INF SPI configuration file does not implement/extend the SPI interface type that owns the ExtensionLoader. The check type.isAssignableFrom(clazz) fails, meaning the configured implementation class is incompatible with the contract. The message includes the interface, the offending class line name, and the mismatch.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java:1274
for (String excludePackage : onlyExtensionClassLoaderPackages) {
if (className.startsWith(excludePackage + ".")) {
// if target classLoader is not ExtensionLoader's classLoader should be excluded
return !Objects.equals(ExtensionLoader.class.getClassLoader(), classLoader);
}
}
}
return false;
}
private void loadClass(
ClassLoader classLoader,
Map<String, Class<?>> extensionClasses,
java.net.URL resourceURL,
Class<?> clazz,
String name,
boolean overridden) {
if (!type.isAssignableFrom(clazz)) {
throw new IllegalStateException(
"Error occurred when loading extension class (interface: " + type + ", class line: "
+ clazz.getName() + "), class " + clazz.getName() + " is not subtype of interface.");
}
boolean isActive = loadClassIfActive(classLoader, clazz);
if (!isActive) {
return;
}
if (clazz.isAnnotationPresent(Adaptive.class)) {
cacheAdaptiveClass(clazz, overridden);
} else if (isWrapperClass(clazz)) {
cacheWrapperClass(clazz);
} else {
if (StringUtils.isEmpty(name)) {
name = findAnnotationName(clazz);
if (name.length() == 0) {View on GitHub (pinned to 3a3043227f)
Solutions
- Open the META-INF file named after the SPI interface (e.g. META-INF/dubbo/org.apache.dubbo.rpc.Protocol) and verify the implementation class FQN is correct and implements the interface.
- If the class is correct, ensure the SPI interface in the config filename exactly matches the @SPI-annotated interface you expect.
- Run 'jar tf your.jar | grep META-INF/dubbo' to find which artifact ships the offending config and fix or exclude it.
- After a rename/refactor, update all SPI config files to the new class name.
Example fix
# before: META-INF/dubbo/org.apache.dubbo.rpc.Protocol myproto=com.example.OldProtocolName # throws [146] if OldProtocolName was renamed or no longer implements Protocol # after myproto=com.example.NewProtocolName
Defensive patterns
Strategy: validation
Validate before calling
// At build/test time, verify every SPI config entry implements the interface
Class<?> iface = MySpi.class;
Class<?> impl = Class.forName(configImplFqn);
if (!iface.isAssignableFrom(impl)) {
throw new IllegalStateException(impl + " does not implement " + iface);
} Prevention
- Validate SPI config files in a build-time test that loads each implementation and checks isAssignableFrom.
- After renaming a class, update all META-INF SPI config files consistently.
- Use 'jar tf' to audit which artifacts ship SPI configs when debugging classpath conflicts.
When it happens
Trigger: A META-INF/dubbo/org.apache.dubbo.rpc.Protocol file (or META-INF/services/ equivalent) contains a line 'someName=com.example.WrongClass' where com.example.WrongClass does not implement org.apache.dubbo.rpc.Protocol. loadClass() is invoked during SPI directory scanning and validates the assignability immediately.
Common situations: Typo in the implementation class FQN in the SPI config file; refactoring moved a class to a different interface but the config was not updated; a fat-jar/shade relocation rewrote class names but left old SPI config files on the classpath; two jars provide conflicting SPI configs where one references a class from an older incompatible version.
Related errors
- No such extension name for the class {} in the config {}
- Extension instance (name: {}, class: {}) couldn't be instant
- Extension type == null
- Exception occurred when loading extension class (interface:
- More than 1 default extension name on extension {}: {}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/de7623148803aa65.
Report an issue: GitHub.