apache/dubbo · error · IllegalStateException

Adaptive Extension doesn't exist (Extension {})!

Error message

Adaptive Extension doesn't exist (Extension {})!

What it means

Thrown by ExtensionLoader.replaceExtension(String name, Class<?> clazz) when the class is annotated @Adaptive but no adaptive class has been previously registered (cachedAdaptiveClass == null). You cannot replace an adaptive extension that does not exist — use addExtension to register it first.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java:712

        }
        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) {
                throw new IllegalStateException("Adaptive Extension doesn't exist (Extension " + type + ")!");
            }

            cachedAdaptiveClass = clazz;
            cachedAdaptiveInstance.set(null);
        }
    }

    @SuppressWarnings("unchecked")
    public T getAdaptiveExtension() {
        checkDestroyed();
        Object instance = cachedAdaptiveInstance.get();
        if (instance == null) {
            if (createAdaptiveInstanceError != null) {
                throw new IllegalStateException(
                        "Failed to create adaptive instance: " + createAdaptiveInstanceError.toString(),
                        createAdaptiveInstanceError);
            }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Use addExtension(null, adaptiveClass) instead of replaceExtension to register the adaptive class for the first time.
  2. Verify whether an adaptive class already exists before trying to replace it.
  3. Check if the SPI interface has @Adaptive methods — if not, Dubbo will not auto-generate an adaptive class.

Example fix

// before — trying to replace non-existent adaptive class
loader.replaceExtension(null, MyAdaptiveClass.class); // @Adaptive but nothing to replace

// after — add first, then replace if needed later
loader.addExtension(null, MyAdaptiveClass.class); // registers adaptive class
// later if updating:
loader.replaceExtension(null, UpdatedAdaptiveClass.class);
Defensive patterns

Strategy: validation

Validate before calling

if (clazz.isAnnotationPresent(Adaptive.class)) {
    boolean adaptiveExists = false;
    try {
        loader.getAdaptiveExtension();
        adaptiveExists = true;
    } catch (Exception ignored) {}
    if (adaptiveExists) {
        loader.replaceExtension(null, clazz);
    } else {
        loader.addExtension(null, clazz); // first-time adaptive registration
    }
}

Prevention

When it happens

Trigger: Calling replaceExtension with an @Adaptive-annotated class when Dubbo has not yet generated or loaded an adaptive class for this SPI type. This can happen if the SPI interface has no @Adaptive methods (so no adaptive class is auto-generated) and no manual adaptive class was previously added.

Common situations: Test setup attempts to replace an adaptive class before any adaptive class exists. The SPI interface was modified to remove @Adaptive methods, so no adaptive class is generated. Developer calls replaceExtension instead of addExtension for the first adaptive registration.

Related errors


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