apache/maven · error · ExtensionResolutionException

Extension {} or one of its dependencies could not be resolve

Error message

Extension {} or one of its dependencies could not be resolved: {}

What it means

BootstrapCoreExtensionManager resolves each .mvn/extensions.xml entry (groupId:artifactId:version, with ${property} interpolation against user then system properties) via PluginDependenciesResolver.resolveCoreExtensionAndFlatten(). If resolution fails (PluginResolutionException: unknown artifact, missing version, unreachable repository, offline mode) or coordinate interpolation fails (InterpolatorException), it is wrapped in ExtensionResolutionException whose message reads 'Extension <id> or one of its dependencies could not be resolved: <cause>'. This happens during CLI bootstrap, before the project builds.

Source

Thrown at compat/maven-embedder/src/main/java/org/apache/maven/cli/internal/BootstrapCoreExtensionManager.java:232

        try {
            /* TODO: Enhance the PluginDependenciesResolver to provide a
             * resolveCoreExtensionAndFlatten method which uses a CoreExtension
             * object instead of a Plugin as this makes no sense.
             */
            Plugin plugin = Plugin.newBuilder()
                    .groupId(interpolator.apply(extension.getGroupId()))
                    .artifactId(interpolator.apply(extension.getArtifactId()))
                    .version(interpolator.apply(extension.getVersion()))
                    .build();

            DependencyResult result = pluginDependenciesResolver.resolveCoreExtensionAndFlatten(
                    new org.apache.maven.model.Plugin(plugin), dependencyFilter, repositories, repoSession);
            return result.getArtifactResults().stream()
                    .filter(ArtifactResult::isResolved)
                    .map(ArtifactResult::getArtifact)
                    .collect(Collectors.toList());
        } catch (PluginResolutionException | InterpolatorException e) {
            throw new ExtensionResolutionException(extension, e);
        }
    }

    private static UnaryOperator<String> createInterpolator(MavenExecutionRequest request) {
        Interpolator interpolator = new DefaultInterpolator();
        UnaryOperator<String> callback = v -> {
            String r = request.getUserProperties().getProperty(v);
            if (r == null) {
                r = request.getSystemProperties().getProperty(v);
            }
            return r != null ? r : v;
        };
        return v -> interpolator.interpolate(v, callback);
    }

    static class SimpleSession extends DefaultSession {
        SimpleSession(
                MavenSession session,

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Read the wrapped cause in the message; verify the exact coordinates exist: search Maven Central or your corporate repo for that groupId:artifactId:version.
  2. Remove -o/--offline or pre-seed the local repository so the extension and its dependencies resolve.
  3. Check settings.xml mirrors: a mirror with <mirrorOf>*</mirrorOf> can block the repository the extension lives in — narrow the mirrorOf pattern.
  4. Define any ${property} used in extension coordinates via .mvn/maven.config (-Dkey=value) or -D on the command line, since only user/system properties are consulted for interpolation.
  5. Add the extension's repository under <repositories> of... note bootstrap uses the effective repositories; prefer declaring needed repos in settings.xml profiles that are active by default.

Example fix

<!-- before (.mvn/extensions.xml): version does not exist -->
<extension>
  <groupId>org.example.build</groupId>
  <artifactId>cool-extension</artifactId>
  <version>2.3.99</version>
</extension>

<!-- after: real released version, property for reuse -->
<extension>
  <groupId>org.example.build</groupId>
  <artifactId>cool-extension</artifactId>
  <version>${cool.ext.version}</version>
</extension>
<!-- .mvn/maven.config -->
<!-- -Dcool.ext.version=2.3.0 -->
Defensive patterns

Strategy: try-catch

Validate before calling

// Embedder: pre-flight check that every extensions.xml entry resolves in the local repo or is fetchable
for (CoreExtension ext : readCoreExtensions(Path.of(".mvn/extensions.xml"))) {
    String gav = ext.getGroupId() + ':' + ext.getArtifactId() + ':' + ext.getVersion();
    if (ext.getVersion().startsWith("${")) {
        requireUserPropertyDefined(ext.getVersion()); // interpolation needs user/system properties
    }
    if (!localRepo.find(gav).isPresent()) {
        LOGGER.warn("Core extension {} not cached; build will fail in offline mode", gav);
    }
}

Try / catch

try {
    mavenCli.doMain(args, workingDir, ...);
} catch (org.apache.maven.cli.internal.ExtensionResolutionException e) {
    String extId = /* parse 'Extension <id> or one of its dependencies...' */;
    report("Core extension " + extId + " unresolvable; cause: " + e.getCause().getMessage());
    // actionable: check repo reachability, mirrors, offline flag, coordinates
}

Prevention

When it happens

Trigger: A .mvn/extensions.xml entry whose coordinates or version do not exist in any reachable repository; a core extension whose transitive dependencies cannot be downloaded; running with -o/--offline without the artifacts cached; ${expr} in coordinates where the property is undefined in user/system properties (fails interpolation); corporate repository requiring credentials that are missing in settings.xml.

Common situations: Enabling a core extension (e.g. a logging or masking extension) whose version was bumped or removed; CI runners without network access or with a narrow mirror <mirrorOf> that excludes the extension's repository; private-registry extensions where the settings.xml distribution-management/server credentials were not applied to the bootstrap repositories; typos in groupId/artifactId.

Related errors


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