apache/maven · error · PluginConfigurationException

A required class was missing during configuration of mojo

Error message

A required class was missing during configuration of mojo ${mojoDescriptor.getId()}: ${e.getMessage()}

What it means

During mojo configuration (not mojo loading) a NoClassDefFoundError escaped: a class needed to convert or assign a configuration value — often the parameter's own type, a custom converter, or a type referenced by a setter — is missing from the plugin realm. Maven captures it, appends a realm dump, and throws PluginConfigurationException so you can trace which jar should contain the class.

Solutions

  1. Take the class name from 'A required class was missing' and locate it in the realm dump: either the jar is absent or the local copy is broken.
  2. Delete that artifact directory under ~/.m2/repository and rebuild with mvn -U to re-download cleanly.
  3. Remove/relax exclusions on the plugin so the artifact carrying the parameter type returns.
  4. Pin the needed library version under <plugin><dependencies> if mediation removed it.
  5. Re-run with -X to inspect the full realm if the dump alone is unclear.

Example fix

// before: corrupted jar in the local repo -> NoClassDefFoundError during configuration
// (fix: remove the broken cached artifacts)
rm -rf ~/.m2/repository/org/example/example-maven-plugin/1.0.0

// after: force a clean, verified re-download
mvn -U verify
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-flight: resolve plugins fully and remove truncated jars that break configuration-time classloading
mvn -B dependency:resolve-plugins
find ~/.m2/repository -name '*.jar' -size -100c -print -delete
mvn -U verify

Type guard

static boolean missingClassDuringConfiguration(PluginConfigurationException e) {
    return e.getCause() instanceof NoClassDefFoundError;
}

Try / catch

try {
    executor.execute(session, mojoExecution);
} catch (PluginConfigurationException e) {
    if (e.getCause() instanceof NoClassDefFoundError ncdf) {
        // message already contains the realm dump; name the jar that should hold ncdf.getClassName()
        reportMissingJarForClass(ncdf.getClassName());
    }
    throw e;
}

Prevention

When it happens

Trigger: A mojo parameter's declared type lives in a dependency that was excluded or lost to mediation; a custom TypeConverter is not on the plugin classpath; a partially downloaded/corrupt jar in the local repository lacks the class file.

Common situations: Aggressive <exclusions> on the plugin; offline builds against a partially cached plugin; plugins whose parameter types come from a separate API artifact that was pruned; interrupted downloads leaving truncated jars.

Related errors


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

Appendix: source

Thrown at impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java:855

                message += " for parameter " + e.getFailedConfiguration().getName();
            }
            message += ": " + e.getMessage();

            throw new PluginConfigurationException(mojoDescriptor.getPluginDescriptor(), message, e);
        } catch (ComponentLookupException e) {
            throw new PluginConfigurationException(
                    mojoDescriptor.getPluginDescriptor(),
                    "Unable to retrieve component configurator " + configuratorId + " for configuration of mojo "
                            + mojoDescriptor.getId(),
                    e);
        } catch (NoClassDefFoundError e) {
            ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
            PrintStream ps = new PrintStream(os);
            ps.println("A required class was missing during configuration of mojo " + mojoDescriptor.getId() + ": "
                    + e.getMessage());
            pluginRealm.display(ps);

            throw new PluginConfigurationException(mojoDescriptor.getPluginDescriptor(), os.toString(), e);
        } catch (LinkageError e) {
            ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
            PrintStream ps = new PrintStream(os);
            ps.println("An API incompatibility was encountered during configuration of mojo " + mojoDescriptor.getId()
                    + ": " + e.getClass().getName() + ": " + e.getMessage());
            pluginRealm.display(ps);

            throw new PluginConfigurationException(mojoDescriptor.getPluginDescriptor(), os.toString(), e);
        } finally {
            if (configurator != null) {
                try {
                    container.release(configurator);
                } catch (ComponentLifecycleException e) {
                    logger.debug("Failed to release mojo configurator - ignoring.");
                }
            }
        }
    }

View on GitHub (pinned to e4093d4e12)