Infrastructure worth keeping — and kept patched.

Gradle remote build cache not working: no FROM-CACHE

Your build runs, nothing fails, and nothing comes from the remote cache. Gradle treats a broken remote cache as non-fatal, so the build carries on without it and the only sign may be one line in the log. Work down this list.

1. Is the build cache switched on?

The buildCache block in settings.gradle(.kts) says where the cache is. It does not turn caching on. Without this line the block does nothing:

# gradle.properties
org.gradle.caching=true

Or pass --build-cache on each run. This is the most common cause.

2. Is the local cache hiding the problem?

Gradle's local cache is on by default and gives hits even when the remote is failing. So FROM-CACHE on its own does not prove the remote works. Take the local cache out of the picture and show remote errors:

rm -rf ~/.gradle/caches/build-cache-1
./gradlew --stop
./gradlew build --build-cache -i

Run it twice. The second run is the one that tells you something.

3. Is the password reaching Gradle?

If the server uses a password and Gradle sends none, every request gets a 401. In our test with Gradle 9.8.0 on macOS, Gradle printed Could not load entry ... response status 401: Unauthorized at the default log level and carried on without the cache. Two things to check:

To test the server's password directly, a 401 means the credentials are wrong and a 404 means they are right and the key just is not there yet:

curl -s -o /dev/null -w '%{http_code}\n' -u gradle:wrong-password \
  https://cache.example.com/some-key

4. Is the URL right, and is it HTTPS?

Keep the trailing slash on the URL. Gradle adds the cache key straight onto it. Gradle also refuses plain http:// unless you set isAllowInsecureProtocol = true. In our test with Gradle 9.8.0, the address 127.0.0.1 was allowed without it, but the name localhost was refused. Use HTTPS in real deployments, because Gradle sends the password with every request.

One trap in test setups: some sample projects run a check that fails any build containing an http:// URL, including the cache URL. That is the check, not the cache.

5. Is the server seeing requests?

curl -s https://cache.example.com/metrics | grep -E 'fscache_cache_(hits|misses)_total'

Run a build and run this again. If neither counter moves, the requests are not arriving. If misses move and hits do not, the cache is working and has not been filled yet, or something in the task inputs changes on every build.

6. Is this client allowed to upload?

If you set isPush to false, or only to true on CI, a laptop only reads. Nothing fills the cache until a machine that may upload has run the build.

Not the same thing: the configuration cache

Gradle may suggest enabling its "configuration cache". That is a different, local feature. It has nothing to do with a remote build cache.

Gradle and Maven setup Questions and answers