apache/maven · error · PluginManagerException
Error resolving version for plugin '${groupId}:${artifactId}
Error message
Error resolving version for plugin '${groupId}:${artifactId}' from the repositories ${repositories}: ${baseMessage} What it means
The POM declares the plugin without a <version>, so Maven had to resolve one from repository metadata, and the version resolver failed — wrapped here as PluginManagerException carrying the PluginVersionResolutionException message (plugin coordinates, repository list, and the concrete reason). Common underlying reasons: no maven-metadata.xml for that plugin group in any reachable repository, metadata unreadable/404, or the plugin only has SNAPSHOT metadata while a release version was requested.
Source
Thrown at impl/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java:965
project.setContextValue(KEY_EXTENSIONS_REALMS, pluginRealms);
}
final String pluginKey = plugin.getId();
ExtensionRealmCache.CacheRecord extensionRecord = pluginRealms.get(pluginKey);
if (extensionRecord != null) {
return extensionRecord;
}
final List<RemoteRepository> repositories = project.getRemotePluginRepositories();
// resolve plugin version as necessary
if (plugin.getVersion() == null) {
PluginVersionRequest versionRequest = new DefaultPluginVersionRequest(plugin, session, repositories);
try {
plugin.setVersion(pluginVersionResolver.resolve(versionRequest).getVersion());
} catch (PluginVersionResolutionException e) {
throw new PluginManagerException(plugin, e.getMessage(), e);
}
}
// TODO: store plugin version
// resolve plugin artifacts
List<Artifact> artifacts;
PluginArtifactsCache.Key cacheKey = pluginArtifactsCache.createKey(plugin, null, repositories, session);
PluginArtifactsCache.CacheRecord recordArtifacts;
try {
recordArtifacts = pluginArtifactsCache.get(cacheKey);
} catch (PluginResolutionException e) {
throw new PluginManagerException(plugin, e.getMessage(), e);
}
if (recordArtifacts != null) {
artifacts = recordArtifacts.getArtifacts();
} else {
try {View on GitHub (pinned to e4093d4e12)
Solutions
- Pin an explicit <version> on the plugin — the immediate fix and long-standing best practice.
- Verify the plugin's maven-metadata.xml exists in a configured repository (browse or curl the group path).
- Add the plugin's groupId to <pluginGroups> or the plugin's repository to <pluginRepositories> if it lives outside the defaults.
- Check the groupId/artifactId spelling — a typo resolves metadata in a nonexistent path.
- If offline (-o) was used, run once online so metadata is cached, or pre-seed the cache.
Example fix
// before: no version, resolver must consult metadata (and fails when it is missing) <plugin> <groupId>org.example</groupId> <artifactId>example-maven-plugin</artifactId> </plugin> // after: always pin an explicit version <plugin> <groupId>org.example</groupId> <artifactId>example-maven-plugin</artifactId> <version>1.2.0</version> </plugin>
Defensive patterns
Strategy: validation
Validate before calling
# fail fast in CI when any plugin lacks an explicit version (the precondition for this error)
python3 - <<'EOF'
import xml.etree.ElementTree as ET
ns = {'m': 'http://maven.apache.org/POM/4.0.0'}
t = ET.parse('pom.xml')
bad = []
for p in t.findall('.//m:plugin', ns):
if p.find('m:version', ns) is None:
bad.append(p.find('m:artifactId', ns).text)
assert not bad, 'plugins without pinned version: ' + ', '.join(bad)
EOF
# and verify the plugin's metadata is reachable
curl -fsSI https://repo.example.com/org/example/example-maven-plugin/maven-metadata.xml Try / catch
// embedder: distinguish version-resolution failure from other plugin manager problems
try {
setupPlugin(project, plugin, session);
} catch (PluginManagerException e) {
if (e.getCause() instanceof PluginVersionResolutionException pvre) {
log.error('pin an explicit <version> for this plugin; metadata reason: {}', pvre.getMessage());
}
throw e;
} Prevention
- Always pin plugin versions — with a version set, this code path is never exercised.
- Add the maven-enforcer-plugin requirePluginVersions rule to enforce pinning repo-wide.
- Make sure internal plugin groups are deployed to repositories listed in pluginRepositories.
- Keep groupId spellings for internal plugins in a snippet library to avoid metadata lookups in wrong paths.
When it happens
Trigger: Version-less <plugin> entry plus: plugin group not present in the configured pluginRepositories (or not proxied by the mirror), missing/invalid maven-metadata.xml for the plugin, running with -o against a cache without prior metadata, or a typo in groupId making resolution look in the wrong path.
Common situations: First use of an internal plugin whose group was never deployed to the repo manager; corporate mirrors blocking external plugin groups; prefix resolution found the plugin (via pluginGroups) but version metadata is absent; air-gapped environments with incomplete proxies.
Related errors
- Unable to determine the latest version
- Unable to determine the release version
- Plugin ${plugin.getId()} or one of its dependencies could no
- Plugin ${plugin.getId()} or one of its dependencies could no
- Cannot read metadata from '{}': {}
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/3d799dae761aa552.
Report an issue: GitHub.