apache/maven · error · UnknownRepositoryLayoutException
Cannot find ArtifactRepositoryLayout instance for: " + layou
Error message
Cannot find ArtifactRepositoryLayout instance for: " + layoutId
What it means
DefaultArtifactRepositoryFactory.createDeploymentArtifactRepository(id, url, layoutId, uniqueVersion) looks the layoutId up in a map of ArtifactRepositoryLayout components wired from the Plexus container. Only the built-in hints 'default' and 'legacy' are registered out of the box; any other id fails the lookup and is reported as UnknownRepositoryLayoutException('Cannot find ArtifactRepositoryLayout instance for: <layoutId>'). The exception is a subclass of InvalidRepositoryException and also carries the offending layoutId via getLayoutId().
Source
Thrown at compat/maven-compat/src/main/java/org/apache/maven/repository/legacy/repository/DefaultArtifactRepositoryFactory.java:66
@Override
public ArtifactRepositoryLayout getLayout(String layoutId) throws UnknownRepositoryLayoutException {
return repositoryLayouts.get(layoutId);
}
@Override
public ArtifactRepository createDeploymentArtifactRepository(
String id, String url, String layoutId, boolean uniqueVersion) throws UnknownRepositoryLayoutException {
ArtifactRepositoryLayout layout = repositoryLayouts.get(layoutId);
checkLayout(id, layoutId, layout);
return createDeploymentArtifactRepository(id, url, layout, uniqueVersion);
}
private void checkLayout(String repositoryId, String layoutId, ArtifactRepositoryLayout layout)
throws UnknownRepositoryLayoutException {
if (layout == null) {
throw new UnknownRepositoryLayoutException(repositoryId, layoutId);
}
}
@Override
public ArtifactRepository createDeploymentArtifactRepository(
String id, String url, ArtifactRepositoryLayout repositoryLayout, boolean uniqueVersion) {
return createArtifactRepository(id, url, repositoryLayout, null, null);
}
@Override
public ArtifactRepository createArtifactRepository(
String id,
String url,
String layoutId,
ArtifactRepositoryPolicy snapshots,
ArtifactRepositoryPolicy releases)
throws UnknownRepositoryLayoutException {
ArtifactRepositoryLayout layout = repositoryLayouts.get(layoutId);View on GitHub (pinned to e4093d4e12)
Solutions
- Use the built-in layout id "default" (Maven 2/3 standard layout) unless you specifically need the Maven 1 "legacy" layout
- Check the exact hint via UnknownRepositoryLayoutException.getLayoutId() and fix typos in the caller
- If a custom layout is genuinely required, register an ArtifactRepositoryLayout component with a matching @Named/hint in the container (or as a Plexus/SI component in an extension)
- Prefer the overload createDeploymentArtifactRepository(id, url, ArtifactRepositoryLayout, uniqueVersion) and pass the layout instance directly, avoiding the string lookup entirely
Example fix
// before
ArtifactRepository repo = factory.createDeploymentArtifactRepository(
"releases", "https://repo.example.com/releases", "maven-default", true);
// after
ArtifactRepository repo = factory.createDeploymentArtifactRepository(
"releases", "https://repo.example.com/releases", "default", true); Defensive patterns
Strategy: validation
Validate before calling
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
private static final Set<String> BUILT_IN_LAYOUTS = Set.of("default", "legacy");
void requireKnownLayout(String layoutId) throws UnknownRepositoryLayoutException {
if (layoutId == null || !BUILT_IN_LAYOUTS.contains(layoutId)
|| repositoryLayouts.get(layoutId) == null) {
throw new UnknownRepositoryLayoutException(repositoryId, layoutId);
}
}
// or skip the string lookup entirely:
factory.createDeploymentArtifactRepository(id, url, defaultLayout /* instance */, true); Try / catch
try {
ArtifactRepository repo = factory.createDeploymentArtifactRepository(id, url, layoutId, true);
} catch (UnknownRepositoryLayoutException e) {
String badLayout = e.getLayoutId(); // exact failing hint
log.error("Layout '{}' is not registered; falling back to 'default'", badLayout);
repo = factory.createDeploymentArtifactRepository(id, url, "default", true);
} Prevention
- Default to the 'default' layout unless a concrete requirement demands otherwise
- Centralize the layout id in one constant so typos cannot spread across call sites
- If you rely on a custom layout component, add a smoke test that looks it up in the container at build startup
When it happens
Trigger: Calling createDeploymentArtifactRepository with a layoutId other than "default" or "legacy" when no custom ArtifactRepositoryLayout component is registered under that role hint in the container; or a custom layout that used to be contributed by an extension/plugin that is no longer on the build classpath.
Common situations: Maven 2-era deployment code passing a homegrown layout id; typos like "defaults" or "maven-default" instead of "default"; uninstalling or renaming a third-party repository-layout extension while old configuration still references its hint.
Related errors
- Cannot find conflict resolver of type: " + type
- Repository identifier missing
- URL missing for repository " + id
- Cannot find ArtifactRepositoryLayout instance for: %s %s
- Unable to retrieve component configurator ${configuratorId}
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/bb03a168721286c4.
Report an issue: GitHub.