apache/dubbo · error · IllegalStateException
More than 1 default extension name on extension {}: {}
Error message
More than 1 default extension name on extension {}: {} What it means
Thrown by cacheDefaultExtensionName() when the @SPI annotation's value() on an SPI interface contains more than one comma-separated name after trimming. The @SPI annotation declares the default extension name; Dubbo only allows exactly one default. A value like @SPI("a,b") is rejected because getDefaultExtension() cannot resolve ambiguity.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java:1036
}
}
}
/**
* extract and cache default extension name if exists
*/
private void cacheDefaultExtensionName() {
final SPI defaultAnnotation = type.getAnnotation(SPI.class);
if (defaultAnnotation == null) {
return;
}
String value = defaultAnnotation.value();
if ((value = value.trim()).length() > 0) {
String[] names = NAME_SEPARATOR.split(value);
if (names.length > 1) {
throw new IllegalStateException("More than 1 default extension name on extension " + type.getName()
+ ": " + Arrays.toString(names));
}
if (names.length == 1) {
cachedDefaultName = names[0];
}
}
}
private void loadDirectoryInternal(
Map<String, Class<?>> extensionClasses, LoadingStrategy loadingStrategy, String type)
throws InterruptedException {
String fileName = loadingStrategy.directory() + type;
try {
List<ClassLoader> classLoadersToLoad = new LinkedList<>();
// try to load from ExtensionLoader's ClassLoader first
if (loadingStrategy.preferExtensionClassLoader()) {
ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();View on GitHub (pinned to 3a3043227f)
Solutions
- Edit the SPI interface annotation to contain exactly one default name: @SPI("singleName").
- If you need conditional/multiple extension selection, use @Activate annotations on implementations or select by name explicitly via getExtension(name) instead of relying on a default.
- If you intended round-robin or fallback, implement a custom selector rather than abusing the default.
Example fix
// before
@SPI("dubbo,rest")
public interface Protocol { ... }
// throws [145] at load time
// after
@SPI("dubbo")
public interface Protocol { ... } Defensive patterns
Strategy: validation
Validate before calling
// Validate the @SPI annotation at build/test time
SPI ann = MySpi.class.getAnnotation(SPI.class);
if (ann != null) {
String[] names = ann.value().trim().split(",");
if (names.length > 1) throw new IllegalStateException("@SPI has multiple defaults: " + ann.value());
} Prevention
- Annotate SPI interfaces with exactly one default name in @SPI.
- Add a unit test asserting the @SPI value has at most one comma-separated token.
- Use @Activate for conditional multi-extension selection instead of multi-default @SPI.
When it happens
Trigger: An SPI interface is annotated with @SPI containing multiple names, e.g. @SPI("dubbo,mock") or @SPI("a,b,c"). cacheDefaultExtensionName() is called during the first extension-class load and splits on NAME_SEPARATOR (comma); if more than one token results, it throws immediately.
Common situations: A custom SPI interface mistakenly lists multiple defaults; copy-paste from an example that intended multiple Activate values (which use different semantics); a fork that changed a single-default @SPI to list fallbacks thinking it would be tried in order.
Related errors
- Extension instance (name: {}, class: {}) couldn't be instant
- Extension type == null
- Exception occurred when loading extension class (interface:
- Error occurred when loading extension class (interface: {},
- No such extension name for the class {} in the config {}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/70b9e2c523f85128.
Report an issue: GitHub.