apache/maven · error · IOException

Could not create local repository at {}

Error message

Could not create local repository at {}

What it means

Before building, DefaultMaven.validateLocalRepository mkdirs() the local repository path (from settings.xml localRepository or -Dmaven.repo.local) and throws IOException if the path is still not a directory afterwards. mkdirs silently fails when a regular file occupies the path, a parent is not writable, the filesystem is read-only, or permissions deny creation. The message names the path.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/DefaultMaven.java:445

        return result;
    }

    private CloseableSession newCloseableSession(MavenExecutionRequest request, WorkspaceReader workspaceReader) {
        return repositorySessionFactory
                .newRepositorySessionBuilder(request)
                .setWorkspaceReader(workspaceReader)
                .build();
    }

    private void validateLocalRepository(MavenExecutionRequest request) throws IOException {
        File localRepoDir = request.getLocalRepositoryPath();

        logger.debug("Using local repository at {}", localRepoDir);

        localRepoDir.mkdirs();

        if (!localRepoDir.isDirectory()) {
            throw new IOException("Could not create local repository at " + localRepoDir);
        }
    }

    private <T> Collection<T> getExtensionComponents(Collection<MavenProject> projects, Class<T> role) {
        Collection<T> foundComponents = new LinkedHashSet<>();
        foundComponents.addAll(lookup.lookupList(role));
        foundComponents.addAll(getProjectScopedExtensionComponents(projects, role));
        return foundComponents;
    }

    protected <T> Collection<T> getProjectScopedExtensionComponents(Collection<MavenProject> projects, Class<T> role) {
        if (projects == null) {
            return Collections.emptyList();
        }

        Collection<T> foundComponents = new LinkedHashSet<>();
        Collection<ClassLoader> scannedRealms = new HashSet<>();

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Inspect the path: `ls -ld <path>` - if a file occupies it, remove/move it and rerun.
  2. Grant write+execute on the directory and all parents for the build user, or choose a writable path via -Dmaven.repo.local or settings.xml.
  3. In containers, mount the repo volume with matching uid/gid or run with `--user $(id -u):$(id -g)`.
  4. Check disk space (`df -h <path>`) and whether the mount is read-only (`mount | grep <path>`).

Example fix

# before: a regular file blocks the repository directory
$ ls -ld /repo
-rw-r--r-- 1 root root 0 /repo

# after
$ rm /repo && mvn -Dmaven.repo.local=/repo package
Defensive patterns

Strategy: validation

Validate before calling

File repo = request.getLocalRepositoryPath();
if (repo.exists() ? !repo.isDirectory() || !repo.canWrite() : !repo.getAbsoluteFile().getParentFile().canWrite()) {
    throw new IOException("Local repository path not usable (file in the way or not writable): " + repo);
}

Prevention

When it happens

Trigger: -Dmaven.repo.local=/some/path where /some/path or a parent lacks write permission; a file (not directory) already exists at the path; read-only container mounts; SELinux/AppArmor denials; disk full.

Common situations: CI containers running as non-root against root-owned volumes; Docker mounts of ~/.m2 with mismatched uid; a typo'd earlier command creating a file where the repo dir should be; locked-down corporate images.

Related errors


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