Maven ·
‹ Previous Next ›
⏱ 5 min read Modified: 2026-11-07

Maven Repository Types: Local (.m2), Maven Central and Corporate

On a developer laptop the shop-web module builds without errors, but on the CI server the same mvn package command fails with Could not find artifact com.examclouds:shop-core:jar:1.0-SNAPSHOT in central (https://repo.maven.apache.org/maven2). The code is identical; the difference is in the repositories. At some point shop-core was installed with mvn install into the local repository ~/.m2/repository of the laptop. The local repository of the CI server is empty, and Maven Central has no such artifact. Below we look at where Maven searches for artifacts and how to make them visible to the whole team.

A Maven repository is a storage of artifacts with a fixed directory layout: Maven takes dependencies and plugins from it and publishes build results to it. An artifact is a file addressed by Maven coordinates: a jar, a war, a pom file, a sources archive or Javadoc. There are two kinds of repositories (often shortened to maven repo or mvn repository): the local one (the ~/.m2/repository directory on your computer) and remote ones — the central repository Maven Central, corporate repositories (Nexus, Artifactory) and third-party ones. Maven always looks for an artifact in the local repository first and downloads it from a remote one only if it is missing.

What a Repository Stores: Artifacts and Their Paths

A Maven artifact repository stores library and project files arranged by their groupId:artifactId:version coordinates. The file path is derived from the coordinates: the dots in groupId become directories, followed by the artifactId and version directories, and the file name is artifactId-version.extension. That is why the local, central and corporate repositories all share the same layout.

For example, the library with the coordinates com.google.code.gson:gson:2.11.0 lives at:

com/google/code/gson/gson/2.11.0/gson-2.11.0.jar
# local:   ~/.m2/repository/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar
# central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar

So a Maven repository is not just a jar repository: next to every jar there are its POM, checksums and metadata. How to choose the coordinates themselves is covered in the sections GAV Coordinates and How to Choose groupId, artifactId and version. A single version directory usually contains several files:

File What it is When it appears
gson-2.11.0.jar The artifact itself (.war when packaging is war) On the first build that needs this dependency
gson-2.11.0.pom The POM of the library: Maven reads its own (transitive) dependencies from it Always together with the artifact; a BOM or a parent POM has only this file
gson-2.11.0-sources.jar, gson-2.11.0-javadoc.jar Sources and documentation (classifiers sources and javadoc) Only when requested by the IDE or a command, for example mvn dependency:sources
*.sha1 Checksums used to verify the integrity of a downloaded file Downloaded from the remote repository together with the file
_remote.repositories A service file: which repository (by id) the artifact came from Created by Maven in the local repository
maven-metadata-*.xml Metadata: the list of versions, the latest SNAPSHOT build For SNAPSHOT versions and when resolving plugin versions

Types of Maven Repositories

Maven has one local repository and any number of remote ones. The local repository is a cache on the developer disk, and Maven checks it first. Remote repositories are reached over the network: the central repository Maven Central (enabled by default), the corporate repository of your company and third-party public repositories. Maven treats every repository except the local one as remote.

Repository Where it is Who fills it When it is used
Local ~/.m2/repository on the developer machine or the CI server Maven when downloading; your mvn install Always, first
Central (Maven Central) https://repo.maven.apache.org/maven2 Open-source library authors via the Central Portal By default, if the artifact is not in the local repository
Corporate A company server: Nexus, Artifactory and similar The development team via mvn deploy; a cache of Central If configured in settings.xml or pom.xml
Third-party public For example, https://jitpack.io or vendor repositories The owner of the repository Only if declared explicitly in <repositories>

Local Repository: the .m2 Directory

By default the Maven local repository is the .m2/repository directory in the user home folder: ~/.m2/repository on Linux and macOS, C:\Users\<name>\.m2\repository on Windows. This .m2 repository (often just called the m2 repo) belongs to one user and is shared by all of that user’s projects: a library downloaded for one project is not downloaded again for another.

Artifacts get into the local repository in two ways: Maven downloads them from remote repositories during a build, and the mvn install command puts the result of your own build there — a jar (or a war or pom, depending on packaging) together with its POM. After that, other projects on the same machine can use it as a regular dependency. A fragment of the directory after building a project with Gson and running mvn install for the project com.examclouds:shop:

~/.m2/repository/
├── com/
│   ├── examclouds/shop/1.0-SNAPSHOT/      # installed by mvn install
│   │   ├── shop-1.0-SNAPSHOT.jar
│   │   ├── shop-1.0-SNAPSHOT.pom
│   │   ├── maven-metadata-local.xml
│   │   └── _remote.repositories
│   └── google/code/gson/gson/2.11.0/       # downloaded from central
│       ├── gson-2.11.0.jar
│       ├── gson-2.11.0.jar.sha1
│       ├── gson-2.11.0.pom
│       ├── gson-2.11.0.pom.sha1
│       └── _remote.repositories
└── org/apache/maven/plugins/...            # plugins are artifacts too

Note the last line: Maven plugins (maven-compiler-plugin, maven-surefire-plugin) are artifacts as well, so the first build of even an empty project downloads dozens of files. The size of the directory depends on your projects; on a working machine it is often several gigabytes. Deleting it is safe: Maven downloads everything it needs again, but your own modules installed with mvn install have to be installed again.

How to change the path. Permanently — with the <localRepository> element in settings.xml; for a single run — with a system property:

mvn package -Dmaven.repo.local=/tmp/m2-clean

A separate empty directory is a handy way to check whether the project builds "from scratch", as on a CI server: this catches the situation from the beginning of the lesson.

Maven Central Repository

Maven Central is the public repository Maven uses by default: it is declared in the built-in Super POM with the id central and the URL https://repo.maven.apache.org/maven2. Practically all open-source Java libraries and frameworks are published there, so most projects need no repository configuration at all.

This is how the central repository is declared in the Super POM (you can see it in the output of mvn help:effective-pom):

<repositories>
    <repository>
        <id>central</id>
        <name>Central Repository</name>
        <url>https://repo.maven.apache.org/maven2</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

You cannot upload your artifact there directly. Publishing goes through the Sonatype Central Portal, and what is checked is not the library code but formal requirements: ownership of the namespace (the groupId is verified through a domain you own or an account, for example io.github.username), sources and Javadoc archives, PGP signatures and POM metadata (name, description, url, license, developers, scm). A published release is immutable: it can be neither overwritten nor deleted, and a fix is shipped as a new version. SNAPSHOT versions are not published to Maven Central, which is why they are disabled for central in the Super POM.

Searching for libraries. The official Maven Central search is central.sonatype.com (the old address is search.maven.org). The popular site mvnrepository.com is an unofficial catalog: it indexes Central and some other repositories, but Maven does not download artifacts from it. How to copy coordinates from these sites correctly is covered in How to Declare a Dependency.

The central repository works over HTTPS only, and since Maven 3.8.1 any HTTP repository is blocked by default — see Current Versions and the Maven Wrapper.

How Maven Resolves a Dependency

For every dependency and plugin, Maven checks the local repository first. If the file is there (and it is not a SNAPSHOT that is due for an update check), it is used without any network access. Otherwise Maven queries the remote repositories one by one until one of them returns the artifact, and stores the file in the local repository.

According to the Maven documentation, remote repositories are queried in this order:

  1. repositories from active profiles in settings.xml (the global one, then the user one);
  2. repositories from the project pom.xml, then from parent POMs, and last — central from the Super POM;
  3. repositories declared in the POM files of dependencies, along the path to the requested artifact.

If a mirror is configured for a repository, the request goes to the mirror URL instead. In the build log a download looks like this:

[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.11.0/gson-2.11.0.pom
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.11.0/gson-2.11.0.pom (11 kB at 52 kB/s)
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.11.0/gson-2.11.0.jar

The word after from is the repository id: it tells you where the file actually came from. A second build prints no such lines — everything is taken from ~/.m2/repository. Maven re-checks SNAPSHOT dependencies in the remote repository according to updatePolicy (once a day by default); see SNAPSHOT vs release.

A failure is cached too. If an artifact was not found (a typo in the version, an unreachable repository), Maven writes a service file marking the failed attempt into the local repository (for example, *.lastUpdated) and does not go to the network for it again until the update interval has passed — even if you have already fixed the configuration. The message looks roughly like this (the wording depends on the Maven version):

[ERROR] Failure to find com.example:report-lib:jar:1.0.0 in https://repo.maven.apache.org/maven2
was cached in the local repository, resolution will not be reattempted until the update interval
of central has elapsed or updates are forced

The mvn -U package flag forces Maven to check the remote repositories again. If that does not help, delete the directory of this version in ~/.m2/repository.

Repositories in pom.xml: repositories and pluginRepositories

To make Maven look for dependencies somewhere other than Maven Central, add a <repositories> section to pom.xml: each repository gets a unique id, a url and switches that allow downloading releases and SNAPSHOT versions. Maven plugins use a separate <pluginRepositories> section with the same elements.

<repositories>
    <repository>
        <id>company-public</id>
        <url>https://nexus.example.com/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>daily</updatePolicy>
        </snapshots>
    </repository>
</repositories>

<pluginRepositories>
    <pluginRepository>
        <id>company-public</id>
        <url>https://nexus.example.com/repository/maven-public/</url>
    </pluginRepository>
</pluginRepositories>

There is no need to declare central in your own pom.xml: it already comes from the Super POM. Values of updatePolicy: always, daily (the default), interval:N (minutes), never.

Declaring repositories in pom.xml makes sense for an open-source project that needs a third-party public repository: then the project builds for anyone who downloads it. Inside a company, the corporate repository URL is usually set not in every project but once — as a mirror in settings.xml. Never put usernames and passwords into pom.xml: the file ends up in Git.

settings.xml: Mirrors, Credentials and the Repository Path

settings.xml is the Maven configuration file of a specific machine, not of a project: the user file ~/.m2/settings.xml and the global conf/settings.xml in the Maven installation directory (when both set the same thing, the user file wins). It defines the local repository path, mirrors of remote repositories, credentials, proxies and profiles with additional repositories.

Element What it sets Example
localRepository The path to the local repository D:/maven/repository
mirrors/mirror Replaces the URL of one or all remote repositories (mirrorOf) All requests go through the corporate Nexus
servers/server Username and password (or token) for the repository or mirror with the same id Access to Nexus for downloads and mvn deploy
proxies/proxy An HTTP proxy for internet access A corporate network without direct access
profiles, activeProfiles Additional repositories and properties for all projects The team SNAPSHOT repository
offline Permanent offline mode (same as the -o flag) true

A typical ~/.m2/settings.xml of a developer in a company: all requests go through the corporate repository, and the credentials are taken from environment variables so that the password is not stored in the file as plain text:

<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0">
    <localRepository>D:/maven/repository</localRepository>

    <mirrors>
        <mirror>
            <id>company-nexus</id>
            <name>Company Nexus</name>
            <url>https://nexus.example.com/repository/maven-public/</url>
            <!-- all repositories, including central -->
            <mirrorOf>*</mirrorOf>
        </mirror>
    </mirrors>

    <servers>
        <server>
            <!-- id must match the mirror or repository id -->
            <id>company-nexus</id>
            <username>${env.NEXUS_USER}</username>
            <password>${env.NEXUS_PASSWORD}</password>
        </server>
    </servers>
</settings>

Values of mirrorOf: * — all repositories; central — Maven Central only; external:* — everything except local addresses (localhost, file://); a comma-separated list with exclusions, for example *,!jitpack. Passwords in settings.xml can also be encrypted with mvn --encrypt-password (this needs a master password in ~/.m2/settings-security.xml). Which settings were actually applied is shown by mvn help:effective-settings.

Heads-up: mirrorOf * also captures your own repositories

A mirror with <mirrorOf>*</mirrorOf> replaces the URL of any repository, including one declared in the <repositories> of the project. You add https://jitpack.io to pom.xml, yet Maven still looks for the artifact in the corporate Nexus and reports Could not find artifact ... in company-nexus: the log shows the mirror id instead of the id of your repository. The fix is to add JitPack to Nexus as a proxy repository or to exclude it from the mirror: <mirrorOf>*,!jitpack</mirrorOf>, where jitpack is the repository id in pom.xml.

Corporate Repository: Nexus and Artifactory

A corporate repository is a remote repository that a company runs on its own server to store its own artifacts and cache public ones. You fully control its content and access, as with the local repository, but it is shared by the whole team and the CI servers. The most common products are Sonatype Nexus Repository and JFrog Artifactory; Maven repositories are also offered by GitHub Packages, GitLab Package Registry and cloud services.

Such a server usually hosts three types of repositories (names as in Nexus; Artifactory has the same idea under the names local, remote and virtual):

Type What it does Example in Nexus
hosted Stores artifacts published by the team with mvn deploy maven-releases, maven-snapshots
proxy Caches a remote repository: the first request downloads the file from Central, later requests are served by the company server maven-central
group Combines several repositories under one URL — this is the URL you put into the mirror maven-public

What a corporate repository gives you:

  • Sharing internal libraries. The shop-core module from the beginning of the lesson is published with mvn deploy and becomes available to every developer and to the CI server.
  • Private code. Access is limited by accounts and permissions on the server, and artifacts never leave the company.
  • Speed and resilience. Libraries from Central are downloaded into the company network once, and builds do not depend on the availability of the internet and external servers.
  • Control. You can block libraries with known vulnerabilities or unsuitable licenses (the features depend on the product and edition).

To connect, a developer usually only needs a mirror and a server in settings.xml, as in the example above; to publish, the project also needs <distributionManagement>.

mvn install vs mvn deploy: Where the Artifact Goes

The mvn install command builds the project and copies the artifact with its POM into the local repository, where only other projects on the same computer can use it. The mvn deploy command does the same and additionally uploads the artifact to the remote repository from <distributionManagement>, where colleagues and CI servers can get it.

Aspect mvn install mvn deploy
Where the artifact goes ~/.m2/repository of the current user The local repository and a remote (corporate) one
Who can use it Only projects on this machine Everyone with access to the remote repository
What has to be configured Nothing <distributionManagement> in pom.xml and a server with the same id in settings.xml
SNAPSHOT file name shop-1.0-SNAPSHOT.jar With a timestamp: shop-1.0-20261107.101530-1.jar
Who usually runs it A developer The CI server after a successful build

The target is configured separately for releases and SNAPSHOT versions; Maven picks the repository by the version suffix of the project:

<distributionManagement>
    <repository>
        <id>company-releases</id>
        <url>https://nexus.example.com/repository/maven-releases/</url>
    </repository>
    <snapshotRepository>
        <id>company-snapshots</id>
        <url>https://nexus.example.com/repository/maven-snapshots/</url>
    </snapshotRepository>
</distributionManagement>
mvn deploy
# Output (fragment):
[INFO] Uploading to company-snapshots: https://nexus.example.com/repository/maven-snapshots/com/examclouds/shop/1.0-SNAPSHOT/shop-1.0-20261107.101530-1.jar
[INFO] Uploaded to company-snapshots: https://nexus.example.com/repository/maven-snapshots/com/examclouds/shop/1.0-SNAPSHOT/shop-1.0-20261107.101530-1.jar (12 kB at 40 kB/s)
[INFO] BUILD SUCCESS

For authentication Maven looks in settings.xml for a <server> element with the id company-snapshots (or company-releases for a release). What mvn install prints and in which order the phases up to install and deploy run is covered in Installing Maven vs the mvn install Command and Maven Build Lifecycle.

Surprise: there is no 1.0-SNAPSHOT.jar in a remote repository

On mvn deploy a SNAPSHOT version is stored with a timestamp and a build number: shop-1.0-20261107.101530-1.jar, and the next deploy produces ...-2.jar. Maven learns which build is the latest from maven-metadata.xml in the version directory. So a script that downloads .../1.0-SNAPSHOT/shop-1.0-SNAPSHOT.jar by a direct link gets a 404, even though 1.0-SNAPSHOT works fine as a dependency. A release version (1.0.0) is stored under its plain name.

Troubleshooting Repository Errors

Most Maven repository problems come down to three causes: the artifact exists only in somebody’s local repository, Maven queries the wrong repository (because of a mirror or a cached failure), or it has no permission to access it. The error message usually contains the repository id — start the diagnosis there.

What you see Cause How to fix it
Could not find artifact com.examclouds:shop-core:jar:1.0-SNAPSHOT in central on CI or on a colleague’s machine The module was installed with mvn install into your local repository only Publish it to the corporate repository (mvn deploy) or build the modules together in one multi-module project
... was cached in the local repository, resolution will not be reattempted ... A failed download attempt was cached mvn -U; if needed, delete the version directory in ~/.m2/repository
status code: 401, reason phrase: Unauthorized (401) No <server>, or its id does not match the mirror/repository id Make the ids identical; check the username and token with mvn help:effective-settings
Blocked mirror for repositories: [... (http://...)] The repository URL uses HTTP, and Maven 3.8.1+ blocks HTTP Switch the URL to HTTPS (for a corporate server, enable HTTPS on it)
A repository from pom.xml "does not work", the log shows a different id A mirror with mirrorOf = * intercepts all requests Exclude the repository in mirrorOf or add it to Nexus as a proxy
Re-running mvn deploy for a release fails with status 400 A hosted release repository forbids redeployment by default Bump the version (1.0.1); only SNAPSHOTs can be overwritten
Fresh changes of a SNAPSHOT dependency are not picked up The updatePolicy check is not due yet (once a day by default) mvn -U package

Frequently Asked Questions

What is the difference between mvnrepository.com and Maven Central?

Maven Central (https://repo.maven.apache.org/maven2) is the repository itself: Maven downloads files from it. mvnrepository.com is an unofficial catalog site: it is convenient for finding libraries and copying a <dependency> snippet, but putting its address into <repositories> makes no sense — it is not a Maven repository. The official Central search is central.sonatype.com.

How do I add a jar that is not on Maven Central to the local repository?

Use mvn install:install-file -Dfile=lib/legacy-sdk.jar -DgroupId=com.vendor -DartifactId=legacy-sdk -Dversion=2.3 -Dpackaging=jar. After that, declare the jar in pom.xml as a regular dependency with these coordinates. It will exist only on your machine, though, so in a team such a file is published to the corporate repository with mvn deploy:deploy-file and the -Durl and -DrepositoryId parameters.

How do I move the Maven local repository to another drive?

Set the new path in the <localRepository> element of ~/.m2/settings.xml (on Windows — C:\Users\<name>\.m2\settings.xml; create the file if it does not exist), for example D:/maven/repository. Move the old directory there or delete it — Maven will download the dependencies again. In IntelliJ IDEA, check that the Maven settings use the same settings.xml. A sample file is in the settings.xml section.

What is the difference between Nexus and Artifactory?

For Maven both do the same job: they store the team artifacts (hosted/local), cache Maven Central (proxy/remote) and combine repositories under one URL (group/virtual). Both support other formats too (npm, Docker, PyPI), and both have a free edition and commercial ones. The choice usually depends on the company infrastructure; the Maven setup is the same for both — a mirror and a server in settings.xml.

Can Maven use several remote repositories at once?

Yes. Maven queries them one by one until one returns the artifact: first repositories from settings.xml profiles, then from pom.xml and its parents, and Maven Central last. Every extra repository slows down the lookup of missing artifacts, so companies combine them into a single group repository in Nexus or Artifactory. Details are in How Maven Resolves a Dependency.

Comments

Please log in or register to have a possibility to add comment.