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

  1. Identify which jars provide the duplicate name using 'jar tf <jar> | grep META-INF/dubbo' and remove or rename one.
  2. Rename your custom extension to a unique name in its META-INF SPI config (e.g., 'mydubbo=com.example.MyProtocol').
  3. 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.
  4. 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

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


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/110af71f80f24478. Report an issue: GitHub.