Debugging log · Signing
"Keystore file not found for signing config"
The release build failed before it could sign anything: Keystore file not found for signing config, with a path. Unlike the "wrong password" keystore error, this one is simpler and more literal — Gradle looked for the keystore at the location your build told it to, and nothing was there. The file is missing, or the path is wrong, or it only exists somewhere Gradle isn't looking.
The short version: your signingConfig points at a keystore path that doesn't resolve on this machine. Fix the path (watch relative-vs-absolute), make sure the file is present where you're building, and read the keystore location and credentials from a properties file or environment variables rather than hardcoding them.
The error
Keystore file '/path/to/release.jks' not found for signing config 'release'.
The path in the message is exactly where Gradle looked. Check whether a file is actually at that location — half the time the answer is simply "no," and the fix is the path.
Cause 1 — a wrong relative path
A relative storeFile is resolved from the module directory, which isn't always where you think. If your config says storeFile file("release.jks") but the file lives in the project root or a keystore/ folder, Gradle won't find it. Point it precisely, relative to the module:
signingConfigs {
create("release") {
storeFile = file("../keystore/release.jks")
// ...
}
}
If in doubt, use a correct absolute path temporarily to confirm the file itself is fine, then convert back to a clean relative one.
Cause 2 — the file only exists on your machine
This is the classic CI failure. Your keystore is on your laptop (and rightly kept out of Git), so it builds locally and fails on a build server that never received it. The fix isn't to commit the keystore — it's to supply it to the build environment securely: as a CI secret file, decoded into place before the build, with the path pointing at where it lands.
Cause 3 — credentials/path hardcoded and missing
If the path and passwords were hardcoded and the file moved, or a teammate's checkout has a different layout, the config breaks for everyone but you. The robust pattern reads the location and credentials from an untracked properties file:
// keystore.properties (git-ignored) storeFile=../keystore/release.jks storePassword=... keyAlias=... keyPassword=...
// build.gradle.kts — load it
val props = Properties().apply {
val f = rootProject.file("keystore.properties")
if (f.exists()) load(f.inputStream())
}
signingConfigs {
create("release") {
storeFile = file(props.getProperty("storeFile"))
storePassword = props.getProperty("storePassword")
keyAlias = props.getProperty("keyAlias")
keyPassword = props.getProperty("keyPassword")
}
}
Now the path and secrets live outside the repo, each environment supplies its own, and a missing file fails loudly instead of leaking a committed keystore.
Keep the keystore and its passwords out of version control, but make the build fail clearly when they're absent — that's better than a hardcoded path that silently works for one person and breaks for everyone else. And back the keystore up somewhere safe; "not found" becomes "lost forever" if there's no copy.
Quick checks
- Is a file actually at the path in the error? If not, that's the whole fix.
- Relative path resolving from the module, not where you assumed?
- Building on CI? The keystore must be provided to that environment, not committed.
- Properties file present and git-ignored, with the right path inside?
Paths and file names above are examples — use your own project's layout.