apache/maven · error · ComponentConfigurationException

Cannot find permitted subclass '{}' for sealed type {}

Error message

Cannot find permitted subclass '{}' for sealed type {}

What it means

A plugin/component configuration uses an implementation='...' hint to choose an implementation of a sealed type, but the hint matches none of the sealed type's permitted subclasses. EnhancedConfigurationConverter.getPermittedSubclass() compares the hint against each permitted subclass's binary name, canonical name, and simple name; zero matches raise this error, chained onto the original lookup failure.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/configuration/internal/EnhancedConfigurationConverter.java:150

            final Class<?> type,
            final String implementation,
            final PlexusConfiguration configuration,
            final ComponentConfigurationException cause)
            throws ComponentConfigurationException {
        final List<Class<?>> matches = new ArrayList<>();
        for (Class<?> permittedSubclass : type.getPermittedSubclasses()) {
            if (implementation.equals(permittedSubclass.getName())
                    || implementation.equals(permittedSubclass.getCanonicalName())
                    || implementation.equals(permittedSubclass.getSimpleName())) {
                matches.add(permittedSubclass);
            }
        }

        if (matches.size() == 1) {
            return matches.get(0);
        }
        if (matches.isEmpty()) {
            throw new ComponentConfigurationException(
                    configuration,
                    "Cannot find permitted subclass '" + implementation + "' for sealed type " + type.getName(),
                    cause);
        }
        matches.sort(Comparator.comparing(Class::getName));

        throw new ComponentConfigurationException(
                configuration,
                "Implementation hint '" + implementation + "' is ambiguous for sealed type " + type.getName() + ": "
                        + matches.stream().map(Class::getName).toList(),
                cause);
    }

    public void processConfiguration(
            final ConverterLookup lookup,
            final Object bean,
            final ClassLoader loader,
            final PlexusConfiguration configuration,

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Use the fully qualified name of a class actually listed by the sealed type (check its javadoc or Class.getPermittedSubclasses())
  2. Fix typos in the implementation attribute value
  3. Omit the implementation attribute to let the converter use its default instantiation path
  4. Align the plugin/library versions so the intended implementation is permitted by the sealed type

Example fix

<!-- before -->
<param implementation="DefaultHandler"/>

<!-- after: fully qualified permitted subclass -->
<param implementation="org.example.api.sealed.FileHandler"/>
Defensive patterns

Strategy: validation

Validate before calling

// Verify an implementation hint resolves before applying configuration
Class<?> sealed = MySealedInterface.class;
String hint = "org.example.api.sealed.FileHandler"; // from the configuration
boolean permitted = Arrays.stream(sealed.getPermittedSubclasses())
        .map(Class::getName)
        .anyMatch(hint::equals);
if (!permitted) {
    throw new IllegalArgumentException("implementation '" + hint + "' is not permitted by " + sealed.getName());
}

Type guard

static Optional<Class<?>> resolvePermitted(Class<?> sealed, String hint) {
    List<Class<?>> matches = Arrays.stream(sealed.getPermittedSubclasses())
            .filter(c -> hint.equals(c.getName()) || hint.equals(c.getCanonicalName()) || hint.equals(c.getSimpleName()))
            .toList();
    return matches.size() == 1 ? Optional.of(matches.get(0)) : Optional.empty();
}

Prevention

When it happens

Trigger: Configuration like <param implementation="MyImpl"> where the target type is a sealed interface and 'MyImpl' equals no Class in type.getPermittedSubclasses(): typo, wrong package, or a class that exists in the plugin realm but is not on the sealed type's permits list.

Common situations: Upgrading a library whose sealed interface replaced or removed a permitted subclass; configuration samples copied from a different library version; using a simple name when the intended class lives in another package.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/b9f5f0a2c0888569. Report an issue: GitHub.