Infrastructure worth keeping — and kept patched.

Maven build cache extension not restoring: the causes

You set up the Apache Maven Build Cache Extension against a self-hosted cache and the second build still compiles everything. Each cause below was reproduced for real. Find your symptom in the logs, then the fix.

First, what a healthy build looks like

The first build stores its result, and it looks alarming because Maven 3.10.0 logs a miss as an error (Maven 3.9.9 logs it as [INFO] Cache item not found):

[INFO] Attempting to restore project demo:demo from build cache
[ERROR] Error downloading cache item: https://cache.example.com//v1.1/demo/demo/ebb9bceba2f7a6bc/buildinfo.xml
[INFO] Saved to remote cache https://cache.example.com//v1.1/demo/demo/ebb9bceba2f7a6bc/demo.jar
[INFO] Saved to remote cache https://cache.example.com//v1.1/demo/demo/ebb9bceba2f7a6bc/buildinfo.xml
[INFO] BUILD SUCCESS

That [ERROR] line is only the server saying it does not have the entry. What matters is the Saved to remote cache lines after it. After deleting target and the extension's local cache folder, the second build:

[INFO] Attempting to restore project demo:demo from build cache
[INFO] Found cached build, restoring demo:demo from cache by checksum ebb9bceba2f7a6bc
[INFO] BUILD SUCCESS

You must delete the local folder to prove the remote works, because the extension keeps its own local cache and will use it first.

Symptom 1: Maven stops with "Unrecognised tag: 'remote'"

Cannot initialize cache because xml config is not valid or not available
Unable to parse cache xml element: Unrecognised tag: 'remote' ...

Cause: the remote element is outside configuration. Fix: move it inside, as in the working file below. Nothing built, and the server saw nothing.

Symptom 2: the build succeeds, but the server stays empty

There are no Saved to remote cache lines, the second build says "Remote cache is incomplete or missing", and the server's status page shows store_entries: 0.

Cause: without saveToRemote="true" the extension reads from the server and never uploads. Fix: add it on the machines that should upload, usually CI.

Symptom 3: "HTTP Status: 401" in the log, and still no uploads

org.eclipse.aether.spi.connector.transport.http.HttpTransporterException: HTTP Status: 401

The build still ends in BUILD SUCCESS, the server stays empty, and the lines Saved to remote cache are missing. In our runs we got exactly this from two different mistakes:

Fix: make the two ids identical and check the password. Maven 3.10 may also print a warning about the credentials being used for an address without a matching repository entry. In our working setup the build behaved the same either way.

Maven build cache and different Java versions: Java 21 and Java 27

Nothing is broken here. The question is whether switching Java makes a cached build stop restoring.

Our advice, not a test result: use one Java version for the builds that fill a shared cache, so you know which Java made what you restore.

For a multi-module project, see Maven build cache extension in a multi-module project.

The working configuration

<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://maven.apache.org/BUILD-CACHE-CONFIG/1.2.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/BUILD-CACHE-CONFIG/1.2.0 https://maven.apache.org/xsd/build-cache-config-1.2.0.xsd">
  <configuration>
    <enabled>true</enabled>
    <remote enabled="true" saveToRemote="true" id="fosterstack-cache">
      <url>https://cache.example.com/</url>
    </remote>
  </configuration>
</cache>

With a password on the server, ~/.m2/settings.xml needs a matching <server> entry with <id>fosterstack-cache</id>. The full walk-through is in Maven build cache extension: remote server setup.

Check the server's side

The status page counts what arrived. After the healthy first build it showed store_entries: 3, and after the restoring build cache_hits: 2. If those stay at zero while your builds run, the problem is between Maven and the server, not in the project. See the HTTP status codes.

How we checked

Symptom runs

Each cause above was reproduced with Maven 3.10.0, extension 1.2.3 and a 0.2.1 server with a password.

Java runs

A one-module Maven project, built five times in each of three series, with mvn verify and JAVA_HOME set for each build. For series B and C we saved mvn -v for every build to confirm which Java ran (series A has only its summary): Temurin 21.0.12.1 or OpenJDK 27 from Homebrew.

Every build used a fresh copy of the project and an empty local build cache. All builds ran on the same Mac, shared one already-filled local Maven repository (offline), and shared the cache server. Each series started on an empty server. Every build ended with BUILD SUCCESS.

BuildSeries B: JavaSeries B: resultSeries C: JavaSeries C: result
121Built27Built
221Restored27Restored
327Restored21Restored
427Restored21Restored
521Restored27Restored

"Restored" means the log said Found cached build, restoring and Maven skipped the compile and test steps. Series A, with the release setting, gave the same pattern as series B.

In series B all five jars had one checksum, 0f4e29a2..., so the jar restored on Java 27 was the jar built on Java 21. In series C all five had another, ddb48271..., the jar built on Java 27. The files inside the two jars differ in a single place. The manifest in the first says Build-Jdk-Spec: 21 and in the second Build-Jdk-Spec: 27. The compiled class inside was byte-for-byte the same in both (we compared it with cmp). Without the release setting the compiler plugin still compiled for Java 8 on both Javas (the log said target 1.8), which is why the class was the same.

The Java runs used Maven 3.10.0 with maven-build-cache-extension 1.2.3 and FosterStack Cache 0.2.1, on macOS (arm64), with Temurin 21.0.12.1 and OpenJDK 27 (Homebrew).

Not tested in the symptom runs: other Maven versions, or extension 1.2.0. Not tested in the Java runs: other Maven or extension versions, other Java vendors, a project whose build settings change with the Java version (for example, profiles that switch on by JDK), and Windows. The second run, below, was on Linux.

Second run: Linux, 0.2.2

The runs above were on a Mac with 0.2.1. We ran this page again on a GitHub-hosted Linux machine with FosterStack Cache 0.2.2, Maven 3.10.0 (and 3.9.9 for one build), extension 1.2.3, Java 21, and Java 27 (Temurin) for the Java runs.

Every run here used a server without a password, except symptom 3. The Mac symptom runs used one with a password. The run and its log are public.

Maven remote cache setup FosterStack home