apache/dubbo · error · IllegalArgumentException

Extension type (${type}) is not an extension, because it is

Error message

Extension type (${type}) is not an extension, because it is NOT annotated by @SPI!

What it means

Thrown by ExtensionDirector.getExtensionLoader(Class<T> type) when the type IS an interface but is NOT annotated with @SPI. Dubbo's extension system only manages interfaces explicitly marked with @SPI — this annotation declares the extension point and optionally specifies a default implementation. Without it, Dubbo refuses to treat the interface as an extension point.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionDirector.java:76

    }

    @Override
    public ExtensionDirector getExtensionDirector() {
        return this;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
        checkDestroyed();
        if (type == null) {
            throw new IllegalArgumentException("Extension type == null");
        }
        if (!type.isInterface()) {
            throw new IllegalArgumentException("Extension type (" + type + ") is not an interface!");
        }
        if (!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type (" + type
                    + ") is not an extension, because it is NOT annotated with @" + SPI.class.getSimpleName() + "!");
        }

        // 1. find in local cache
        ExtensionLoader<T> loader = (ExtensionLoader<T>) extensionLoadersMap.get(type);

        ExtensionScope scope = extensionScopeMap.get(type);
        if (scope == null) {
            SPI annotation = type.getAnnotation(SPI.class);
            scope = annotation.scope();
            extensionScopeMap.put(type, scope);
        }

        if (loader == null && scope == ExtensionScope.SELF) {
            // create an instance in self scope
            loader = createExtensionLoader0(type);
        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Add the @SPI annotation to the interface: @SPI("defaultImplName") public interface MyExtension { ... }.
  2. Import org.apache.dubbo.common.extension.SPI to resolve the annotation.
  3. If using a third-party interface that you cannot annotate, wrap it in your own @SPI-annotated interface.

Example fix

// before — missing @SPI annotation
public interface MyLoadBalance {
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation);
}

// after — annotate with @SPI
@SPI("random")
public interface MyLoadBalance {
    <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!type.isAnnotationPresent(SPI.class)) {
    throw new IllegalArgumentException(
        type + " must be annotated with @SPI to be used as a Dubbo extension point");
}
ExtensionLoader<T> loader = director.getExtensionLoader(type);

Type guard

static <T> boolean hasSpiAnnotation(Class<T> type) {
    return type != null && type.isInterface() && type.isAnnotationPresent(SPI.class);
}

Try / catch

try {
    ExtensionLoader<T> loader = director.getExtensionLoader(type);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("NOT annotated with @SPI")) {
        log.error("Interface lacks @SPI annotation — add it to declare the extension point", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getExtensionLoader() with a plain Java interface that lacks the @SPI annotation. For example, passing a standard library interface (like java.lang.Runnable) or a custom interface you forgot to annotate. Also triggered when a custom interface was previously annotated but the annotation was removed during refactoring.

Common situations: Developer creates a custom SPI interface but forgets @SPI annotation. The @SPI annotation import was removed during IDE auto-import cleanup. Migrating from a framework where SPI registration works differently (e.g., Java ServiceLoader without annotations).

Related errors


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