Infrastructure worth keeping — and kept patched.

Gradle remote build cache authentication and 401 errors

How to put a password on a self-hosted build cache and give Gradle the right one, three ways to supply it, and what you see when it is wrong. Every output below is from a real run: a 0.2.1 server and Gradle 9.8.0 on macOS.

Turn on a password on the server

FSCACHE_USERNAME=gradle FSCACHE_PASSWORD=<a long secret> ./fscache

This is HTTP Basic Auth. The health and metrics paths stay open without a password, so monitoring still works. The status page does not. For a second, read-only login see let CI write, developers only read.

Tell Gradle the password

In settings.gradle.kts:

// FosterStack Cache — remote Gradle build cache.
// https://github.com/fosterstack/cache
buildCache {
    remote<HttpBuildCache> {
        url = uri("https://cache.example.com/")
        isPush = true
        credentials {
            username = "gradle"
            password = System.getenv("FSCACHE_PASSWORD")
        }
    }
}

Keep the credentials block even where the server has no password. I tested a client with this block against a server with authentication switched off: the build stored an entry and the next build got a hit, so one config works against both a test server and a real one.

Three ways to supply the password

All three were tested and gave :compileJava FROM-CACHE:

What a wrong or missing password looks like

Gradle treats a broken remote cache as non-fatal, so the build still succeeds, just without the cache. In my runs it printed this at the default log level, with a wrong password and with none:

Could not load entry d4f2de693b561fd2c5d60b17a9232d6f from remote build cache: Loading entry from 'http://127.0.0.1:18099/d4f2de693b561fd2c5d60b17a9232d6f' response status 401: Unauthorized

If you see that line, the password Gradle sent was wrong or missing. To test the server directly, a 401 means wrong credentials and a 404 means the credentials are right and the key is not stored yet. See the status codes.

Do I need to restart the Gradle daemon?

Not in my test. I started a daemon with no password, exported the right one in the same shell, and the next build used it (same daemon process, no restart) and got FROM-CACHE. Then I exported a wrong one and the next build printed the 401 line straight away. If a password still seems ignored on your setup, ./gradlew --stop is a quick way to rule the daemon out. I only tested macOS with Gradle 9.8.0.

Use HTTPS

Gradle sends the password with every request, so over plain HTTP it travels in the clear. Gradle refuses plain http:// unless you opt in with isAllowInsecureProtocol; in my test the address 127.0.0.1 was let through without it, but the name localhost was refused. Put real servers behind HTTPS.

Related: Gradle remote build cache not working and who can write to a remote build cache.

Gradle build cache tutorial FosterStack home