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

  1. Use the built-in layout id "default" (Maven 2/3 standard layout) unless you specifically need the Maven 1 "legacy" layout
  2. Check the exact hint via UnknownRepositoryLayoutException.getLayoutId() and fix typos in the caller
  3. 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)
  4. 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

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


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