apache/dubbo · error · IllegalArgumentException

Extension type == null

Error message

Extension type == null

What it means

Thrown by ExtensionDirector.getExtensionLoader(Class<T> type) when the type argument is null. Dubbo's SPI system requires a non-null interface class to resolve the corresponding ExtensionLoader. This is the first guard in the extension resolution pipeline — a null type means no meaningful lookup is possible.

Source

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

            this.extensionPostProcessors.add(processor);
        }
    }

    public List<ExtensionPostProcessor> getExtensionPostProcessors() {
        return extensionPostProcessors;
    }

    @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);
        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Inspect the stack trace to find which code path passes null to getExtensionLoader and trace the source of the Class<T> argument.
  2. Ensure the class reference is loaded via the correct ClassLoader and is not null before calling getExtensionLoader.
  3. Check that the relevant Dubbo module dependency (e.g., dubbo-rpc-api, dubbo-registry-api) is on the classpath so that the interface class constant resolves.
  4. If using shade/relocate, verify the relocation rules cover the package of the SPI interface.

Example fix

// before
ExtensionLoader<MySpi> loader = director.getExtensionLoader(spiClass); // spiClass is null

// after
if (spiClass == null) {
    throw new IllegalStateException("MySpi class not loaded — check dubbo-rpc-api dependency");
}
ExtensionLoader<MySpi> loader = director.getExtensionLoader(spiClass);
Defensive patterns

Strategy: validation

Validate before calling

if (type == null) {
    throw new IllegalArgumentException("SPI type must not be null — check classpath and ClassLoader");
}
ExtensionLoader<T> loader = director.getExtensionLoader(type);

Type guard

static <T> boolean isValidSpiType(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("Extension type == null")) {
        log.error("SPI type was null — likely a missing dependency or ClassLoader issue", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling extensionDirector.getExtensionLoader(null) directly, or more commonly passing a class reference that was resolved to null at runtime (e.g., a Class.forName() that failed silently, a static field that was not initialized, or a class that was shaded/relocated away during a dependency upgrade).

Common situations: Maven shade plugin relocated a package but code still references the old class constant which resolved to null. A custom ScopeModel or ExtensionDirector subclass forgot to pass the type. A plugin/module integration passes a class loaded from a different ClassLoader that returned null. After a Dubbo version upgrade where an SPI interface was renamed or moved.

Related errors


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