Maven: Configuring Maven

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the section bibliography.

This page is written against Apache Maven 3.10.0 (released on 27 September 2026), with Maven 3.9.16 and Maven 4.0.0-rc-7 (a release candidate) run wherever they differ. Every example marked as run was executed on JDK 26 on 2026-10-16, on macOS (Apple silicon), in a scratch copy of the tidepool build: a parent POM with one module and nothing else. Output that comes from a run is shown as printed, except that the scratch paths are shortened to <project> and <lab> and that lines are removed with grep where the text says so. Anything that could not be run here (Windows, a package manager, a real corporate proxy) is labelled "not run here".

Maven is configured in two different senses, and the two are easy to confuse. A project is configured by its POM, which says what to build and is the same for everybody. Maven itself is configured by files and variables that say how this machine, this user or this checkout runs Maven: how much memory the JVM gets, which options every command receives, which extensions are loaded, where the local repository is. This page is about the second kind. The POM is on POM Fundamentals, the command-line options on Running Maven (CLI), and settings.xml (servers, mirrors, proxies, profiles) on settings.xml & Password Encryption. Installing Maven and the JAVA_HOME question are on Installation. The running scenario is described on the section landing page; for the other two tools see Ant: Properties and Gradle.

Where Maven reads its configuration

The official page lists the places in one paragraph each. Put into one table, with the level at which each applies:

Place Level What it carries Travels with the project?

MAVEN_OPTS environment variable

Shell or machine

JVM options for the JVM that runs Maven, such as heap size or -D system properties.

No

MAVEN_ARGS environment variable (Maven 3.9.0 and later)

Shell or machine

Command-line arguments inserted before the ones typed.

No

mavenrc files, ~/.mavenrc

Machine or user

Shell commands run by the launcher script, normally to set the two variables above or JAVA_HOME.

No

~/.m2/settings.xml and conf/settings.xml in the installation

User and installation

Local repository, servers, mirrors, proxies, profiles.

No

.mvn/maven.config

Project (checkout)

Command-line arguments, one per line.

Yes

.mvn/jvm.config

Project (checkout)

JVM options for Maven.

Yes

.mvn/extensions.xml

Project (checkout)

Core extensions loaded before the build starts.

Yes

~/.m2/extensions.xml and conf/extensions.xml (Maven 3.10)

User and installation

Core extensions for every build.

No

The rule of thumb is the one in the table’s last column. Whatever every contributor and the CI server must share belongs in .mvn, committed with the code. Whatever is personal or tied to a machine (a JDK location, a proxy, a mirror, credentials) belongs in the environment, a mavenrc file or settings.xml. The directory layout of the installation, where conf/ lives, is on Installation.

The scratch project used on this page

All the runs below read one value, a user property called who, with the Help plugin’s evaluate goal. The helper function is the whole of the tooling: mvn stands for the Maven under test and -q -N -DforceStdout print only the value, without running the modules.

ev() {
  mvn -q -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate \
      -Dexpression="$1" -DforceStdout "${@:2}"
  echo
}

The project is a parent POM (io.tidepool:tidepool-parent, packaging pom) with one module app, and a .mvn directory next to the parent POM. With no configuration at all the property is not set, which evaluate reports:

ev who
null object or invalid expression

Each section below sets who in a different place and shows what Maven sees.

This helper function and project are this page’s own lab setup, not an example from the Maven documentation.

MAVEN_OPTS

MAVEN_OPTS holds options for the Java Virtual Machine that runs Maven. The official page gives the example of memory settings, -Xms256m -Xmx512m. It is read by the launcher script and passed to java before the main class, so it accepts any JVM option, including -D system properties. To make the effect visible, ask the JVM to print its flags and keep the line that shows the maximum heap size:

MAVEN_OPTS="-Xmx512m -XX:+PrintFlagsFinal" ev project.artifactId | grep -w MaxHeapSize
   size_t MaxHeapSize                              = 536870912                                 {product} {command line}

That is 512 MiB, and the flag came from the command line. The run used Maven 3.10.0; 3.9.16 and 4.0.0-rc-7 print the same value. MAVEN_OPTS affects the JVM that runs Maven, not the JVMs Maven starts to run tests, which are configured on the Surefire plugin (Testing with Surefire), and not the compiler.

MAVEN_ARGS

Since Maven 3.9.0, MAVEN_ARGS carries arguments that are passed to Maven before the ones typed on the command line. The official example is -B -V checkstyle:checkstyle: options and even goals. It suits a CI server that should always run in batch mode, without having to edit each job. The next section shows how it ranks against the other sources of arguments; for now, one property set in MAVEN_ARGS while .mvn/maven.config (below) also sets it:

cat .mvn/maven.config
ev who
MAVEN_ARGS="-Dwho=args" ev who
-Dwho=config
config
args

MAVEN_ARGS wins over maven.config. The same three results came out of Maven 3.9.16, 3.10.0 and 4.0.0-rc-7.

The mavenrc files

The launcher script sources /usr/local/etc/mavenrc, /etc/mavenrc and ~/.mavenrc (in that order) before it looks for Java, unless MAVEN_SKIP_RC is set. The official page describes .mavenrc as defining "environment variables used when Maven builds the project". On Windows the file is %USERPROFILE%\mavenrc_pre.cmd for Maven 3 and %USERPROFILE%\mavenrc.cmd for Maven 4 (not run here). The use of the file to choose a JDK is shown on Installation; here it sets the two variables of the previous sections. A scratch home directory holds this .mavenrc:

export MAVEN_OPTS="-Xmx700m -XX:+PrintFlagsFinal"
export MAVEN_ARGS="-Dwho=mavenrc"
HOME=<lab>/home ev who | grep -w "MaxHeapSize\|mavenrc"
MAVEN_SKIP_RC=1 HOME=<lab>/home ev who
   size_t MaxHeapSize                              = 738197504                                 {product} {command line, ergonomic}
mavenrc
config

The first run took the heap size (700 MiB, rounded up by the JVM) and the property from the file. The second, with MAVEN_SKIP_RC set, ignored the file, and who came from maven.config again. Two details of this run matter. mavenrc is plain shell, so it needs export, and it is read by the launcher script, not by Java: the run changed the shell variable HOME, which the script uses, and that is the reason it worked. Java finds the user’s home directory in another way, as the section on the local repository shows.

The .mvn directory

A directory called .mvn at the top of the project is the project-level configuration. The official page says it "may be checked into version control". It holds up to three files, all optional: maven.config, jvm.config and extensions.xml. Maven 4 adds more, listed at the end of this section. The same directory also holds wrapper/ when the project uses the Maven Wrapper (Maven Wrapper), and the quickstart archetype of Getting Started now generates a .mvn directory with a jvm.config and a maven.config.

How the directory is found

The launcher script looks for .mvn starting in the current directory and moving up through the parents, until it finds one. Running a command inside a module therefore still uses the .mvn of the multi-module root. With -f, the lookup starts from the POM that is named:

cd app && ev who
cd / && ev who -f <project>/pom.xml
Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472)
Maven home: <scratch>/tools/apache-maven-3.10.0
Java version: 26, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-26.jdk/Contents/Home
Default locale: es_ES, platform encoding: UTF-8, time zone: Europe/Madrid
OS name: "mac os x", version: "27.0.1", arch: "aarch64", family: "mac"
config
Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472)
Maven home: <scratch>/tools/apache-maven-3.10.0
Java version: 26, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-26.jdk/Contents/Home
Default locale: es_ES, platform encoding: UTF-8, time zone: Europe/Madrid
OS name: "mac os x", version: "27.0.1", arch: "aarch64", family: "mac"
config

In both cases the value config comes from the root .mvn/maven.config. The five version lines are there because that file contains -V (see below), not because of the -q of the helper. Maven 3.9.16 and 4.0.0-rc-7 found the file in the same two situations (the value was config in all three; the version lines are not repeated). Maven 4 also uses the directory as the marker of the project root; without one it prints the warning described on Getting Started.

maven.config

maven.config holds command-line arguments that are added to every run. The official page gives -T3 -U --fail-at-end as an example. Since Maven 3.9.0 each argument goes on a line of its own, and lines that begin with # are comments; Maven 3.8.x and older did not support comments (not run here, there is no such Maven on this machine). A file that uses an option together with its value must also keep them on separate lines when the option takes a separate value. Here is the file that the run in the previous section read:

# defaults for every build of this project
-B
-V
-T
2
-Dwho=config

-B is batch mode, -V prints the version first, and -T followed by 2 on the next line is the same as -T 2: two build threads. Running without -q shows all three at work. Only lines that the grep below removes (the plugin prefix lookups, which differ on a cold local repository) were left out; the output is from Maven 3.10.0:

mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who | grep -v "auto-discovered"
Apache Maven 3.10.0 (c43a36b8d67be7e0805a411bc0898af1a51f5472)
Maven home: <scratch>/tools/apache-maven-3.10.0
Java version: 26, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk-26.jdk/Contents/Home
Default locale: es_ES, platform encoding: UTF-8, time zone: Europe/Madrid
OS name: "mac os x", version: "27.0.1", arch: "aarch64", family: "mac"
[INFO] Scanning for projects...
[INFO]
[INFO] Using the MultiThreadedBuilder implementation with a thread count of 2
[INFO]
[INFO] ----------------< org.example.tidepool:tidepool-parent >----------------
[INFO] Building tidepool-parent 1.0.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- help:3.5.2:evaluate (default-cli) @ tidepool-parent ---
[INFO] No artifact parameter specified, using 'org.example.tidepool:tidepool-parent:pom:1.0.0-SNAPSHOT' as project.
[INFO]
config
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.965 s (Wall Clock)
[INFO] Finished at: 2026-10-16T14:40:07+02:00
[INFO] ------------------------------------------------------------------------

The "thread count of 2" line is the proof that -T, 2 was read as an option and its value. Maven 3.9.16 and 4.0.0-rc-7 printed the same thread count line. Typical contents of a maven.config are --no-transfer-progress, --fail-at-end, a -T, and the properties of a CI-friendly build (-Drevision=..., see CI-Friendly Versions). Keep it free of anything personal: a profile that only one developer needs is better activated by that developer in the shell.

Who wins: maven.config, MAVEN_ARGS and the command line

The three sources of arguments are applied in a fixed order, and for a property that is set more than once the one applied last wins. A property set in all three places:

ev who
MAVEN_ARGS="-Dwho=args" ev who
MAVEN_ARGS="-Dwho=args" ev who -Dwho=cli
config
args
cli

The order is .mvn/maven.config, then MAVEN_ARGS, then the command line, so the project supplies defaults, the environment adjusts them, and what is typed has the last word. The output was identical on Maven 3.9.16, 3.10.0 and 4.0.0-rc-7. A .mavenrc that exports MAVEN_ARGS, as above, takes part as the environment, which is why mavenrc beat config in the previous section.

jvm.config

jvm.config holds JVM options for Maven, one or more per line, and is the project-level counterpart of MAVEN_OPTS. The official page says it makes MAVEN_OPTS and .mavenrc unnecessary for per-project settings: the file is committed, and everybody gets the same heap and the same system properties without configuring a shell. This file sets a heap and a property, and asks the JVM to print its flags:

-Xmx300m
-XX:+PrintFlagsFinal
-Dbase.dir=${MAVEN_PROJECTBASEDIR}
ev base.dir | grep -w "MaxHeapSize\|base.dir\|null.*\|/private.*"

The grep keeps the heap line and the value of base.dir. Results by version:

Maven Heap size line Value of base.dir

3.9.16

MaxHeapSize = 318767104 (300 MiB, rounded)

null object or invalid expression: the text ${MAVEN_PROJECTBASEDIR} was not expanded.

3.10.0

MaxHeapSize = 318767104

<project>, the root directory of the project.

4.0.0-rc-7

MaxHeapSize = 318767104

<project>

Expanding MAVEN_PROJECTBASEDIR inside jvm.config is listed in the Maven 3.10.0 release notes. It is useful to point an option at a file kept in the repository, such as -Djava.util.logging.config.file=... or a truststore.

Two further differences between Maven 3 and Maven 4 showed up in the same experiments. The first is the order in which jvm.config and MAVEN_OPTS are combined. When two options conflict, the JVM keeps the last one. The launcher script of Maven 3.9.16 and 3.10.0 builds the options as the contents of jvm.config followed by MAVEN_OPTS (line 214 of the 3.10.0 script); the script of Maven 4.0.0-rc-7 appends the contents of jvm.config after MAVEN_OPTS. With -Xmx300m in the file and MAVEN_OPTS=-Xmx512m:

Maven 3.9.16      MaxHeapSize = 536870912   (MAVEN_OPTS wins)
Maven 3.10.0      MaxHeapSize = 536870912   (MAVEN_OPTS wins)
Maven 4.0.0-rc-7  MaxHeapSize = 318767104   (jvm.config wins)

In Maven 3 the person running the build can therefore override the project; in Maven 4 the project can force its value. Check this if a build is moved between the two.

The second difference is quoting. Maven 3 splits jvm.config into words with the shell, and a quotation mark is not interpreted. An option that contains a space and is written with quotes made the JVM fail to start. The file contained one line, -Dwith.space="a b":

ev with.space
Error: Could not find or load main class b"
Caused by: java.lang.ClassNotFoundException: b"

That is the output of Maven 3.9.16 and 3.10.0. Maven 4.0.0-rc-7, whose distribution contains a Java helper for reading the file (bin/JvmConfigParser.java), printed a b. A Maven 3 file should avoid values with spaces.

The example in the official page is -Xmx2048m -Xms1024m -XX:MaxPermSize=512m -Djava.awt.headless=true. It is out of date. The MaxPermSize option was removed together with the permanent generation in Java 8, and a modern JVM refuses to start with it. This is what a file containing exactly that line did on Maven 3.10.0 with JDK 26:

Unrecognized VM option 'MaxPermSize=512m'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Use only the heap options of that line (and -Djava.awt.headless=true, which is still valid).

extensions.xml

A core extension is a library that is loaded into Maven itself, before the build starts, and can replace or add components: for example the Build Cache extension, a Develocity extension, or a custom lifecycle. It is different from a build extension declared inside a POM (<build><extensions>), which is only known after the POM has been read. The page Extensions covers what extensions can do and how they are written; this section is only about where they are declared.

Until Maven 3.2.5 an extension had to be copied by hand into lib/ext of the installation, which meant changing every developer’s Maven. The mechanism of .mvn/extensions.xml replaced that. The file lists Maven coordinates, with the same groupId, artifactId and version as any dependency, and Maven downloads the extension and its transitive dependencies. The following file loads the Build Cache extension, version 1.3.0:

<?xml version="1.0" encoding="UTF-8"?>
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.1.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.1.0 https://maven.apache.org/xsd/core-extensions-1.1.0.xsd">
  <extension>
    <groupId>org.apache.maven.extensions</groupId>
    <artifactId>maven-build-cache-extension</artifactId>
    <version>1.3.0</version>
  </extension>
</extensions>

Running Maven 3.10.0 in the project, the extension announces itself before Maven starts scanning for projects. The grep keeps only the extension’s own lines, and the path was shortened:

mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who | grep -i "cache"
[INFO] Cache configuration is not available at configured path <project>/.mvn/maven-build-cache-config.xml, cache is enabled with defaults
[INFO] Using XX hash algorithm for cache

(The extension then also reports that caching is disabled for the parent project, because it has packaging pom.) The cache itself is the subject of Build Performance: Cache, Parallel Builds & mvnd.

Before Maven 3.10 only the project could declare core extensions this way. The Maven 3.10.0 release notes add "support for user-wide extensions (in ~/.m2/extensions.xml) and installation-wide extensions (in $MAVEN_HOME/conf/extensions.xml)", in addition to the project’s. The same extension file was placed in each of the three locations (for the user one, the home directory was redirected with -Duser.home, see the next section) and the "Using XX hash" line of the extension was counted:

Location of the file 3.9.16 3.10.0 4.0.0-rc-7

.mvn/extensions.xml (project)

loaded

loaded

loaded

~/.m2/extensions.xml (user)

ignored

loaded

loaded

conf/extensions.xml (installation)

ignored

loaded

not run here

For the installation-wide file a copy of each distribution was used, so that the real installation was not modified. The installation-wide location was not run on Maven 4.0.0-rc-7, but the configuration table in the next section lists maven.installation.extensions as ${maven.installation.conf}/extensions.xml and maven.user.extensions as ${maven.user.conf}/extensions.xml.

User-wide and installation-wide extensions apply to every build of the machine, including builds of projects that never heard of them, so they suit tools that observe or accelerate (a build scanner, a mirror selector) rather than ones that change the output. A project that needs a core extension to build correctly should declare it itself, in .mvn/extensions.xml.

What Maven 4 adds to .mvn

Maven 4 reads the same three files and gives the directory a more formal definition. The conf/maven-system.properties file of the 4.0.0-rc-7 distribution defines three directories and the files inside them:

maven.installation.conf = ${maven.home}/conf
maven.user.conf         = ${user.home}/.m2
maven.project.conf      = ${session.rootDirectory}/.mvn

On top of these, the settings, toolchains and extensions files exist at three levels (maven.installation.settings, maven.user.settings, maven.project.settings, and the same for toolchains and extensions), so .mvn/settings.xml is a project-level settings file in Maven 4 (not run here). Properties can also be set from files rather than the command line: conf/maven-user.properties of the distribution includes, when they exist, ${maven.user.conf}/maven-user.properties, maven.properties in the same directory, and the two names in .mvn. A file .mvn/maven-user.properties with the line who=userprops made Maven 4.0.0-rc-7 print:

ev who
userprops

and Maven 3.10.0, on the same project, printed null object or invalid expression. The distribution’s own comment says that maven.properties "will be removed in Maven 4.1.0" and only maven-user.properties will be loaded, so use that name. These properties are user properties, the same as -D ones.

The local repository

Every artifact that Maven downloads or installs goes to the local repository, which defaults to ~/.m2/repository in Maven 3 (and to ${maven.user.conf}/repository, the same place, in the Maven 4 configuration table). Three mechanisms change it.

settings.xml

The official guide puts <localRepository> in the user’s settings.xml, and adds that the path "must be an absolute path":

<settings>
  ...
  <localRepository>/path/to/local/repo/</localRepository>
  ...
</settings>

To prove the setting is read, the run redirected the JVM’s notion of the home directory with -Duser.home (set in MAVEN_OPTS) to the scratch home, whose .m2/settings.xml contains <localRepository> pointing at <lab>/home/shared-repo. Setting HOME, as for .mavenrc, would not have been enough: Java does not take user.home from that variable on this system.

MAVEN_OPTS="-Duser.home=<lab>/home" ev settings.localRepository
<lab>/home/shared-repo

maven.repo.local

The system property maven.repo.local overrides the setting, and, because it is a property, it can be set in maven.config or MAVEN_ARGS:

ev settings.localRepository -Dmaven.repo.local=<project>/cli-repo
<project>/cli-repo

The next run put a relative path in .mvn/maven.config, a common way to give a project its own local repository (-Dmaven.repo.local=.mvn/local-repo). The path is resolved against the directory the command is run from, not against the directory of .mvn:

ev settings.localRepository
cd app && ev settings.localRepository
<project>/.mvn/local-repo
<project>/app/.mvn/local-repo

That is Maven 3.10.0; 3.9.16 and 4.0.0-rc-7 gave the first line when run from the root. Running inside the module created a second repository under app. Prefer an absolute path, and remember that a per-project repository downloads everything again, once for each project.

Chained repositories: maven.repo.local.tail

Since Maven 3.9.0 a read-only "tail" of one or more repositories can be consulted before Maven goes to the network, while writes go to the main local repository. This is how a CI image can ship a pre-populated cache and still run each job with a clean, disposable repository. The experiment counted the artifacts downloaded by the same Help plugin run into a new, empty local repository, once without and once with the existing ~/.m2/repository as the tail (Maven 3.10.0):

mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who -Dmaven.repo.local=<lab>/r
mvn -N org.apache.maven.plugins:maven-help-plugin:3.5.2:evaluate -Dexpression=who -Dmaven.repo.local=<lab>/r \
    -Dmaven.repo.local.tail=<home>/.m2/repository
70 downloads, 18 JARs, 49 POMs
3 downloads, 0 JARs, 0 POMs

(The two lines were obtained by counting the "Downloaded from" lines of Maven’s output; the three downloads of the second run were metadata files for the plugin lookup.) The other keys of the family, from the Maven configuration table, are maven.repo.local.tail.ignoreAvailability (default true), maven.repo.local.head (Maven 4.0.0: prepends instead of appends) and maven.repo.local.recordReverseTree (3.9.0, false by default), which, when true, records in the local repository why an artifact is there. That last key was tried here, and no .tracking directory appeared for the Help plugin run; it is a diagnostic for a build with dependencies, and it is not demonstrated.

Repositories to download from, mirrors and the layout of the local repository are on Repositories, Mirrors & Repository Managers.

Parallel artifact resolution

The configuring guide notes that by default Maven downloads up to five artifacts at once, and that -Dmaven.artifact.threads=1 reduces it, permanently through MAVEN_OPTS (for example export MAVEN_OPTS=-Dmaven.artifact.threads=3). That text was written for the old resolver; the property name was not checked against Maven 3.10.0’s resolver, and no run was made (not run here). The reactor’s own parallelism is a different thing and is controlled with -T, which belongs in maven.config.

Shell completion

Neither distribution used for this page (3.10.0 and 4.0.0-rc-7) contains a completion script: a search of both unpacked trees for files with "complet" in the name found nothing, and the launcher scripts do not mention it. Completion for the mvn command is therefore something the packager or the user adds. The Apache project does not publish one for the Maven 3 command; a widely used community script is maven-bash-completion. It was not installed or run here, so nothing is claimed about how well it knows Maven 3.10’s options or plugins. Package managers may install a completion file next to Maven (not run here). Maven 4’s distribution adds the interactive shell mvnsh (not run here).

The configuration keys

Besides plugin parameters, Maven has its own keys, which are plain system or user properties that configure the core and the resolver. The reference is the "Maven Configuration Options" table in the Maven 4 documentation, generated from the code, with a default and the version that introduced each key. "Since" refers to when the key appeared in the documentation; a key marked 4.0.0 might be absent from Maven 3. This selection is from the 4.0.0-rc-7 table:

Key Purpose Default Since

maven.user.conf, maven.project.conf, maven.installation.conf

The three configuration directories.

${user.home}/.m2, ${session.rootDirectory}/.mvn, ${maven.home}/conf

4.0.0

maven.repo.local

The local repository.

${maven.user.conf}/repository

3.0.0

maven.repo.local.tail

Read-only chained local repositories (comma-separated).

none

3.9.0

maven.repo.local.recordReverseTree

Record why an artifact is in the local repository.

false

3.9.0

maven.build.timestamp.format

Format of maven.build.timestamp; a model property (see below).

yyyy-MM-dd'T'HH:mm:ssXXX

3.0.0

maven.plugin.validation

Plugin validation level (inline reports in the output).

inline

3.9.2

maven.plugin.validation.excludes

Plugins to exclude from validation.

none

3.9.6

maven.resolver.validation

default, mild or off; off is "as in Maven 3.9.x".

default

3.10.0

maven.session.versionFilter

A semicolon-separated list of filters on version ranges (for example h(5) for the highest five).

none

3.10.0

maven.resolver.transport

Resolver transport: default, wagon, apache, jdk or auto.

default

4.0.0

maven.style.color

Colour of the output: auto, always or never.

auto

4.0.0

maven.repo.central

URL of Maven Central; the MAVEN_REPO_CENTRAL variable supplies it.

https://repo.maven.apache.org/maven2

4.0.0

maven.maven3Personality

Make Maven 4 behave like Maven 3.

false

4.0.0

The table also has the maven.logger.* keys, maven.consumer.pom.* keys for the consumer POM (see Maven 4: POM Model & Consumer POM) and maven.relocations.entries for user-defined relocations. Which of them Maven 3.10.0 honours is documented in its own release notes and not in this table, so test a key before depending on it.

One entry behaves differently from the others. maven.build.timestamp.format is a model property, read from the POM. A property build.stamp was defined as ${maven.build.timestamp} and the format was set in the POM’s <properties> to yyyyMMdd-HHmm; the build printed the same value on Maven 3.9.16, 3.10.0 and 4.0.0-rc-7, and a -Dmaven.build.timestamp.format=yyyy on the command line had no effect:

20261016-1239

The unmodified output without the property is the default format with a trailing Z, for example 2026-10-16T12:39:04Z.

Choosing where a setting belongs

You want to…​ Put it in…​ Why

Give every contributor and CI the same heap

.mvn/jvm.config

It is versioned with the code. Remember the Maven 3 versus 4 order against MAVEN_OPTS.

Run every build in batch mode with two threads

.mvn/maven.config

One option per line; a developer can still override with the command line.

Always add --no-transfer-progress on CI only

MAVEN_ARGS in the CI job

It does not change the checkout and wins over maven.config.

Choose the JDK that runs Maven

JAVA_HOME, or a mavenrc file

See Installation; use toolchains for the JDK that compiles (Compiling & Toolchains).

Load a build scanner on every build of a machine

~/.m2/extensions.xml (Maven 3.10 and later)

Not needed in the repository; ignored by 3.9.16.

Pin a Maven version for a project

The wrapper in .mvn/wrapper

See Maven Wrapper.

Move the local repository

settings.xml or maven.repo.local

Absolute paths only.

Share company-wide project information

A parent POM, not Maven’s configuration

The guide says installation and user configuration "cannot be used to add shared project information".

Problems and their usual causes are collected in Troubleshooting & Best Practices. Moving to the release candidate changes some of the above (the jvm.config order, quoting, new .mvn files); see Migrating to Maven 4.