apache/dubbo · error · IllegalStateException
Duplicate extension {} name {} on {} and {}
Error message
Duplicate extension {} name {} on {} and {} What it means
Thrown by saveInExtensionClass() when two distinct implementation classes are registered under the same SPI name and the second registration is not marked overridden. Dubbo disallows two different classes for one name within a single ExtensionLoader; the first wins and the conflicting second triggers this error. It is also logged via COMMON_ERROR_LOAD_EXTENSION and the name is added to unacceptableExceptions, which makes later getExtension(name) throw findException instead of returning either.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java:1358
cachedNames.put(clazz, name);
}
}
/**
* put clazz in extensionClasses
*/
private void saveInExtensionClass(
Map<String, Class<?>> extensionClasses, Class<?> clazz, String name, boolean overridden) {
Class<?> c = extensionClasses.get(name);
if (c == null || overridden) {
extensionClasses.put(name, clazz);
} else if (c != clazz) {
// duplicate implementation is unacceptable
unacceptableExceptions.add(name);
String duplicateMsg = "Duplicate extension " + type.getName() + " name " + name + " on " + c.getName()
+ " and " + clazz.getName();
logger.error(COMMON_ERROR_LOAD_EXTENSION, "", "", duplicateMsg);
throw new IllegalStateException(duplicateMsg);
}
}
/**
* cache Activate class which is annotated with <code>Activate</code>
* <p>
* for compatibility, also cache class with old alibaba Activate annotation
*/
@SuppressWarnings("deprecation")
private void cacheActivateClass(Class<?> clazz, String name) {
Activate activate = clazz.getAnnotation(Activate.class);
if (activate != null) {
cachedActivates.put(name, activate);
} else if (Dubbo2CompactUtils.isEnabled() && Dubbo2ActivateUtils.isActivateLoaded()) {
// support com.alibaba.dubbo.common.extension.Activate
Annotation oldActivate = clazz.getAnnotation(Dubbo2ActivateUtils.getActivateClass());
if (oldActivate != null) {
cachedActivates.put(name, oldActivate);View on GitHub (pinned to 3a3043227f)
Solutions
- Identify which jars provide the duplicate name using 'jar tf <jar> | grep META-INF/dubbo' and remove or rename one.
- Rename your custom extension to a unique name in its META-INF SPI config (e.g., 'mydubbo=com.example.MyProtocol').
- If overriding is intentional, use the overridden=true path (Dubbo's loading strategy / @SPI value ordering) so the later config replaces the earlier one rather than conflicting.
- Run mvn dependency:tree to find duplicate versions of dubbo-* artifacts and exclude the stale one.
Example fix
# before: two jars both declare # jar1: META-INF/dubbo/...Protocol -> dubbo=com.a.A # jar2: META-INF/dubbo/...Protocol -> dubbo=com.b.B # throws [148] # after: rename in the custom jar # jar2: META-INF/dubbo/...Protocol -> mydubbo=com.b.B
Defensive patterns
Strategy: validation
Validate before calling
// Detect duplicate SPI names across classpath at startup
Map<String, List<URL>> seen = new HashMap<>();
Enumeration<URL> urls = cl.getResources("META-INF/dubbo/" + iface.getName());
while (urls.hasMoreElements()) {
parseLines(urls.nextElement()).forEach((k, v) ->
seen.computeIfAbsent(k, x -> new ArrayList<>()).add(v));
}
seen.forEach((k, v) -> { if (new HashSet<>(v).size() > 1) log.warn("duplicate SPI name {}: {}", k, v); }); Prevention
- Use unique extension names for custom implementations; do not reuse built-in Dubbo names.
- Run mvn dependency:tree to catch duplicate dubbo-* artifact versions.
- Audit META-INF SPI configs across all jars with 'jar tf' when integrating a new module.
When it happens
Trigger: Two jars on the classpath both provide a META-INF SPI config line with the same name key but different implementation class FQNs. For example, dubbo-rpc-dubbo and a custom jar both declare 'dubbo=com.xxx.ProtocolImpl'. Without overridden=true on the later load, the duplicate is detected in saveInExtensionClass.
Common situations: Including a custom extension jar that reuses a built-in Dubbo extension name (e.g., redefining 'dubbo' Protocol); two versions of the same Dubbo module jar on the classpath providing duplicate SPI entries; a fat-jar that bundles conflicting transitive SPI configs.
Related errors
- More than 1 adaptive class found: {}, {}
- Extension name ${name} already exists (Extension ${type})!
- Adaptive Extension already exists (Extension ${type})!
- Extension instance (name: {}, class: {}) couldn't be instant
- Extension type == null
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/110af71f80f24478.
Report an issue: GitHub.