When building a Release APK or Android App Bundle in Android Studio, Gradle may fail with “SigningConfig is missing required property storeFile”.
SigningConfig is missing required property 'storeFile'
This means that a signing configuration exists, but Gradle has not received a valid keystore file through the storeFile property.
Android Gradle Plugin defines storeFile as the keystore file used for signing. The current SigningConfig API also includes separate storePassword, keyAlias, keyPassword, and storeType properties. :contentReference[oaicite:11]{index=11}
Google’s current Android build documentation shows a Release SigningConfig that sets storeFile = file("myreleasekey.keystore") and then assigns that SigningConfig to the Release build type. :contentReference[oaicite:12]{index=12}
This article explains the common causes of the error and how to fix it with Kotlin DSL, Groovy, properties files, environment variables, and CI/CD signing setups.
- What Does “SigningConfig is missing required property storeFile” Mean?
- Common Situations
- Common Causes
- 1. storeFile Was Never Set
- 2. storeFile Resolves to null
- 3. keystore.properties Was Not Loaded
- 4. The Keystore Path Environment Variable Is Missing
- 5. The Relative Path Is Based on the Wrong Directory
- 6. The Keystore Was Moved
- 7. An Empty SigningConfig Was Created
- 8. Release References the Wrong SigningConfig
- Step 1: Inspect the SigningConfig
- Step 2: Confirm That the Keystore Exists
- Solution 1: Set storeFile with Kotlin DSL
- Solution 2: Set storeFile with Groovy
- Solution 3: Test with an Absolute Path
- Solution 4: Load the Path from keystore.properties
- Solution 5: Make Sure storeFile Exists in the Properties File
- Solution 6: Do Not Use an Empty storeFile Value
- Solution 7: Load the Keystore Path from an Environment Variable
- Solution 8: Check the Environment Variable
- Solution 9: Fail Early When the Environment Variable Is Missing
- Solution 10: Validate Properties Explicitly
- Solution 11: Assign the Correct SigningConfig to Release
- Solution 12: Keep SigningConfig Definition Clear
- Solution 13: Use a Keystore Outside the Project
- Solution 14: Use rootProject.file for a Root-Relative Path
- Solution 15: Verify Keystore Restoration in CI/CD
- Solution 16: Check the CI Working Directory
- Solution 17: Do Not Commit the Production Keystore Just to Fix the Error
- Solution 18: Verify the Keystore Itself
- Solution 19: Run Gradle Sync
- Solution 20: Clean and Rebuild
- What Should storeFile Point To?
- Does the Keystore Have to Use a .jks Extension?
- Missing storeFile vs Missing Keystore File
- If a Different Signing Error Appears After Fixing storeFile
- Why Does Debug Work?
- Fastest Troubleshooting Order
- If the Problem Still Occurs
- Summary
What Does “SigningConfig is missing required property storeFile” Mean?
An Android Release signing configuration normally contains:
storeFile storePassword keyAlias keyPassword
storeFile identifies the actual keystore file:
storeFile = file("release.jks")
If that value is missing or resolves to null, Gradle does not know which keystore should provide the signing key.
Key point: For this specific error, inspect storeFile before spending time on aliases or passwords.
Common Situations
- After adding a Release SigningConfig
- After migrating from Groovy to Kotlin DSL
- After moving signing data into
keystore.properties - After moving the project to another computer
- During a CI/CD Release build
- After switching to environment-variable-based signing
- After moving the keystore to another directory
- When sharing signing configurations across product flavors
- When a Release build type references an incomplete SigningConfig
Common Causes
1. storeFile Was Never Set
For example:
signingConfigs { create("release") { storePassword = "password" keyAlias = "release" keyPassword = "password" } }
There is no storeFile value.
2. storeFile Resolves to null
For example:
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
If the property is missing, the result is null.
3. keystore.properties Was Not Loaded
The properties file may not exist, may have the wrong filename, or may never be loaded by the Gradle script.
4. The Keystore Path Environment Variable Is Missing
A CI build may expect:
KEYSTORE_PATH
but receive no value.
5. The Relative Path Is Based on the Wrong Directory
file("release.jks") resolves relative to the Gradle project’s context.
The file may exist in the repository but not at the path that the module build script expects.
6. The Keystore Was Moved
For example:
Old: app/release.jks
New:
keys/release.jks
but the Gradle path was never updated.
7. An Empty SigningConfig Was Created
signingConfigs { create("release") }
This creates the SigningConfig but does not configure its required signing information.
8. Release References the Wrong SigningConfig
A fully configured Release SigningConfig may exist while the build type points to an incomplete staging or custom config.
Step 1: Inspect the SigningConfig
Open the module-level build.gradle.kts or build.gradle.
Look for:
storeFile = file("release.jks")
Google’s current Kotlin DSL example sets storeFile, storePassword, keyAlias, and keyPassword in the Release SigningConfig. :contentReference[oaicite:13]{index=13}
Step 2: Confirm That the Keystore Exists
Windows PowerShell:
Get-Item .\release.jks
macOS or Linux:
ls -l release.jks
Verify the exact path used by Gradle.
Solution 1: Set storeFile with Kotlin DSL
android { signingConfigs { create("release") { storeFile = file("release.jks") storePassword = "STORE_PASSWORD" keyAlias = "release" keyPassword = "KEY_PASSWORD" } }
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
}
This matches the current Release signing structure documented by Google. :contentReference[oaicite:14]{index=14}
Solution 2: Set storeFile with Groovy
android { signingConfigs { release { storeFile file("release.jks") storePassword "STORE_PASSWORD" keyAlias "release" keyPassword "KEY_PASSWORD" } }
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Do not mix Kotlin DSL assignment syntax with Groovy syntax.
Solution 3: Test with an Absolute Path
Windows:
storeFile = file("C:/AndroidKeys/release.jks")
macOS:
storeFile = file("/Users/user/AndroidKeys/release.jks")
Linux:
storeFile = file("/home/user/AndroidKeys/release.jks")
If an absolute path works, investigate the original relative path.
Important: Do not permanently commit a developer-specific absolute path to a shared repository. Use it only to diagnose the path problem.
Solution 4: Load the Path from keystore.properties
Example:
storeFile=/Users/user/AndroidKeys/release.jks storePassword=STORE_PASSWORD keyAlias=release keyPassword=KEY_PASSWORD
Kotlin DSL:
import java.util.Properties
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("keystore.properties")
if (keystorePropertiesFile.exists()) {
keystorePropertiesFile.inputStream().use {
keystoreProperties.load(it)
}
}
android {
signingConfigs {
create("release") {
storeFile = file(
keystoreProperties.getProperty("storeFile")
)
storePassword =
keystoreProperties.getProperty("storePassword")
keyAlias =
keystoreProperties.getProperty("keyAlias")
keyPassword =
keystoreProperties.getProperty("keyPassword")
}
}
}
Solution 5: Make Sure storeFile Exists in the Properties File
This is incomplete:
storePassword=STORE_PASSWORD keyAlias=release keyPassword=KEY_PASSWORD
Add:
storeFile=/Users/user/AndroidKeys/release.jks
Solution 6: Do Not Use an Empty storeFile Value
This is also invalid:
storeFile=
Verify that the property contains a real path.
Solution 7: Load the Keystore Path from an Environment Variable
val keystorePath = System.getenv("KEYSTORE_PATH")
android {
signingConfigs {
create("release") {
storeFile = file(keystorePath)
storePassword = System.getenv("KSTOREPWD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEYPWD")
}
}
}
This only works if KEYSTORE_PATH is actually defined.
Solution 8: Check the Environment Variable
macOS or Linux:
printenv KEYSTORE_PATH
Windows PowerShell:
$env:KEYSTORE_PATH
If nothing is returned, configure the variable before running Gradle.
Solution 9: Fail Early When the Environment Variable Is Missing
val keystorePath = System.getenv("KEYSTORE_PATH") ?: error("KEYSTORE_PATH is not set")
android {
signingConfigs {
create("release") {
storeFile = file(keystorePath)
}
}
}
This produces a much clearer configuration error than allowing a missing value to reach the signing task.
Solution 10: Validate Properties Explicitly
val storeFilePath = keystoreProperties.getProperty("storeFile") ?: error("storeFile is missing in keystore.properties")
storeFile = file(storeFilePath)
This is especially useful in shared projects and CI/CD pipelines.
Solution 11: Assign the Correct SigningConfig to Release
Check for mistakes such as:
buildTypes { getByName("release") { signingConfig = signingConfigs.getByName("staging") } }
If staging does not define storeFile, signing fails.
Use the intended configuration:
signingConfig = signingConfigs.getByName("release")
Solution 12: Keep SigningConfig Definition Clear
A clear structure is:
android { signingConfigs { create("release") { ... } }
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
}
This makes it easier to see which signing configuration a build type uses.
Solution 13: Use a Keystore Outside the Project
A keystore does not need to live inside the repository.
For example:
storeFile = file("../keys/release.jks")
Make sure the relative path is resolved from the location you expect.
Solution 14: Use rootProject.file for a Root-Relative Path
storeFile = rootProject.file("keys/release.jks")
This can reduce confusion between project-root and module-relative paths.
Solution 15: Verify Keystore Restoration in CI/CD
If CI reconstructs the keystore from a secret, verify that the file exists before Gradle runs.
macOS or Linux:
ls -l "$KEYSTORE_PATH"
Windows PowerShell:
Get-Item $env:KEYSTORE_PATH
Solution 16: Check the CI Working Directory
A local configuration such as:
file("release.jks")
may work on your computer but fail when CI restores the keystore somewhere else.
Make the restoration path and Gradle’s storeFile agree.
Solution 17: Do Not Commit the Production Keystore Just to Fix the Error
Google’s current Android documentation warns developers to keep keystores and private keys secure, and it recommends not storing Release signing passwords directly in build files. :contentReference[oaicite:15]{index=15}
Recommended: Use local secret properties, environment variables, CI/CD secret storage, or another approved secret-management mechanism.
Solution 18: Verify the Keystore Itself
After fixing storeFile, test the keystore:
keytool -list -v -keystore release.jks
Confirm that the store password works and the expected alias exists.
Solution 19: Run Gradle Sync
After modifying the signing configuration, run:
File → Sync Project with Gradle Files
Then rebuild the Release artifact.
Solution 20: Clean and Rebuild
macOS or Linux:
./gradlew clean ./gradlew assembleRelease
Windows:
gradlew.bat clean gradlew.bat assembleRelease
For an App Bundle:
./gradlew bundleRelease
What Should storeFile Point To?
storeFile must point to the actual keystore file.
Correct:
storeFile = file("release.jks")
Incorrect:
storeFile = file("keys")
The second example points to a directory rather than a keystore.
The Android Gradle Plugin API defines storeFile as the store file used when signing. :contentReference[oaicite:16]{index=16}
Does the Keystore Have to Use a .jks Extension?
No.
The current SigningConfig API also provides storeType independently of storeFile. :contentReference[oaicite:17]{index=17}
JKS:
storeFile = file("release.jks") storeType = "JKS"
PKCS12:
storeFile = file("release.p12") storeType = "PKCS12"
Missing storeFile vs Missing Keystore File
These are related but different problems:
storeFile not configured → SigningConfig has no keystore file value
storeFile configured but file is missing
→ The configured path points to no existing keystore
The first can produce the required-property error discussed here. The second normally leads to a file/path-related failure.
If a Different Signing Error Appears After Fixing storeFile
You may then see:
Keystore was tampered with, or password was incorrect
Failed to read key from store
Alias ... does not exist
This can mean that Gradle has successfully moved past the missing-storeFile stage.
Next verify the store password, key password, and key alias.
Why Does Debug Work?
Debug builds are normally signed automatically with a debug keystore.
Release builds require an explicitly configured signing setup. Google’s current build-variant documentation states that Gradle does not sign Release APKs or AABs unless signing is explicitly configured. :contentReference[oaicite:18]{index=18}
Fastest Troubleshooting Order
- Open the Release SigningConfig.
- Confirm that
storeFileis present. - Confirm that the keystore file exists.
- If using
keystore.properties, verify itsstoreFileproperty. - If using environment variables, verify that the keystore path is defined.
- Confirm that the Release build type uses the correct SigningConfig.
- Run Gradle Sync.
- Build the Release artifact again.
If the Problem Still Occurs
Verify all of the following:
storeFileis configured.storeFiledoes not resolve to null.- The path is not an empty string.
- The keystore file exists.
- The relative path is based on the correct directory.
keystore.propertiesexists.keystore.propertiescontainsstoreFile.- The keystore path environment variable exists.
- CI/CD restores the keystore to the expected location.
- The Release build type does not reference another incomplete SigningConfig.
- Kotlin DSL and Groovy syntax are not mixed.
- You synced and rebuilt the project.
Summary
Android Studio “SigningConfig is missing required property storeFile” means that the Release SigningConfig does not contain a valid keystore file.
The Android Gradle Plugin API formally defines storeFile as the store file used for signing. :contentReference[oaicite:19]{index=19}
For Kotlin DSL, start with:
signingConfigs { create("release") { storeFile = file("release.jks") storePassword = "STORE_PASSWORD" keyAlias = "release" keyPassword = "KEY_PASSWORD" } }
Then assign it to the Release build type:
buildTypes { getByName("release") { signingConfig = signingConfigs.getByName("release") } }
Google’s current build documentation uses this same pattern for configuring Release signing. :contentReference[oaicite:20]{index=20}
If the project uses keystore.properties or environment variables, do not assume that the presence of the loading code means a value was actually loaded. Confirm that a real path reaches storeFile.
Finally, do not solve the problem by committing a production keystore or plaintext passwords to a public repository. Keep signing keys and credentials securely managed. :contentReference[oaicite:21]{index=21}
