Run a repository manager as a caching proxy rather than copying all of Maven Central. The Maven mirror guide says mirroring the entire repository violates the usage policy and can get you banned. A proxy fetches only what your builds ask for, and your builds then point at it through mirrorOf.
Mirror versus proxy
A full mirror copies everything, a very large set that you must keep in sync. A caching proxy stores artifacts the first time someone requests them and serves later requests locally. For almost every organisation the second is enough, and it is what the Maven project recommends.
How Maven picks a mirror
Mirrors are configured in settings.xml in your home .m2 directory. Each has an id, a url and a mirrorOf naming the repository ID it replaces. Central's ID is central.
<mirror>
<id>internal-repository</id>
<url>https://repo.example.com/proxy</url>
<mirrorOf>*</mirrorOf>
</mirror>
Three rules from the guide matter for security.
- A repository can have at most one mirror. Maven does not combine several. It picks the first match. To present several repositories as one, use a repository manager.
- With
mirrorOfset to*, every repository request goes through your mirror. It must hold all required artifacts or proxy to other repositories. - With several mirrors, Maven first looks for an exact match on the ID, then uses the first declared mirror that matches by wildcard rules. Declaration order matters.
The mirrorOf values
| Value | Meaning |
|---|---|
* | All repository IDs |
external:* | Everything except localhost and file based repositories |
external:http:* | All HTTP repositories except localhost (since Maven 3.8.0) |
repo,repo1 | A list of IDs |
!repoId | Excludes an ID, combined with a wildcard |
Watch the whitespace. The docs warn that !repo1, * mirrors nothing, while !repo1,* mirrors everything except repo1. A stray space can silently turn your control off.
Why a single route helps
If every build goes through one proxy, you get one place for access logs, one place to block a bad coordinate and one place to add scanning. Builds that skip the mirror, because a project declares its own repository with a different ID, are the ones you cannot see.
Using * closes that gap, because a repository declared inside a pom is also redirected. Using external:* leaves local and file repositories alone, which suits integration test setups.
Steps
- Deploy a repository manager as a caching proxy with TLS and authentication.
- Distribute a
settings.xmlwith amirrorOfof*to developers and CI. - Block direct access from build hosts to Central and other public repositories.
- Keep release and snapshot rules separate on the proxy.
- Review the access log for requests from clients that bypass it.
Credentials
The mirror page does not cover authentication. It points to separate guides on deployment and security settings and on encrypting passwords. Read those before putting credentials in settings.xml, and avoid committing the file.
Safeguard's dependency scanning and SBOM generation can show what your builds pulled through the proxy, with a free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Click through the demo and watch how a result ties back to a specific artifact, which is what you want from any registry you run.
Quick check
Can I give one repository two mirrors for failover?
No. Maven allows at most one mirror per repository and picks the first match. Use a repository manager for aggregation.
What does mirrorOf with a space after the comma do?
The guide says !repo1, * mirrors nothing, while !repo1,* mirrors everything except repo1.
Sources
Last reviewed: 19 October 2026.