All my information inside key.properties and and build.gradle is correct. But I can't do the app release I keep getting "Cannot Recover Key".
The console shows me this message:
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:signReleaseBundle'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.FinalizeBundleTask$BundleToolRunnable
> Failed to read key upload from store "D:\flutter_projects\first_project\rock_paper_scissors_2\android\app\upload-keystore.jks": Cannot recover key
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.
BUILD FAILED in 1s
Running Gradle task 'bundleRelease'... 1,899ms
Gradle task bundleRelease failed with exit code 1
I don't know what to do! Please, help me!
My question is different from the others, because:
I hope it helps understand better my situation. Glad if you can help me!
The "Cannot recover key" error specifically means that the signing process is failing because it can't access the private key within your keystore using the provided password and alias. Gradle needs this private key to digitally sign your app, which is essential for release builds on the Play Store.
Troubleshooting Steps
Double-Check the Obvious (Again):
key.properties
File: Open this file and very carefully examine the values.
storePassword
: The password you used when creating the keystore (upload-keystore.jks
).keyPassword
: The password you used when creating the key alias inside the keystore. This is often the same as storePassword
, but it doesn't have to be.keyAlias
: The exact alias you gave to your key when creating the keystore. This is case-sensitive.storeFile
: The correct path to your keystore file. Use absolute paths to avoid problems. It's crucial that Gradle can find this file. If you're not sure, print the current project directory and then set your path correctly.build.gradle
(app level): Verify that you're correctly referencing the properties from key.properties
. The code should look something like this (but with your values):
android {
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true // Enable ProGuard/R8 for release builds
shrinkResources true // Remove unused resources
}
}
}
keytool -list -v -keystore your_keystore_path.jks -alias your_alias
Replace your_keystore_path.jks
with the actual path to your keystore file and your_alias
with the alias you're using. It will prompt you for the keystore password. If that fails, the storePassword
in key.properties
is definitely wrong. If it asks for the alias's password after you've provided the keystore password, this is the password for the keyPassword
.
Environment Variables (Preferred)
Instead of hardcoding passwords in key.properties
, consider using environment variables. This is much more secure.
How to set environment variables:
Windows: setx MYAPP_UPLOAD_STORE_PASSWORD "your_password"
(This sets the variable persistently. You might need to restart your IDE or even your computer for it to take effect.)
macOS/Linux: export MYAPP_UPLOAD_STORE_PASSWORD="your_password"
(This sets the variable for the current session. Add this to your .bashrc
or .zshrc
file for persistence.)
Update build.gradle
:
android {
signingConfigs {
release {
storeFile file(System.getenv("MYAPP_UPLOAD_STORE_FILE"))
storePassword System.getenv("MYAPP_UPLOAD_STORE_PASSWORD")
keyAlias System.getenv("MYAPP_UPLOAD_KEY_ALIAS")
keyPassword System.getenv("MYAPP_UPLOAD_KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true // Enable ProGuard/R8 for release builds
shrinkResources true // Remove unused resources
}
}
}
MYAPP_UPLOAD_STORE_FILE=D:/flutter_projects/first_project/rock_paper_scissors_2/android/app/upload-keystore.jks
MYAPP_UPLOAD_STORE_PASSWORD=your_keystore_password
MYAPP_UPLOAD_KEY_ALIAS=your_alias
MYAPP_UPLOAD_KEY_PASSWORD=your_key_password
Make sure to replace your_keystore_password
, your_alias
, and your_key_password
with the correct values.
Keystore Corruption:
keytool -genkeypair -v -keystore upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias your_alias
Follow the prompts to create the keystore and set passwords. Carefully record these passwords! Update your key.properties
and build.gradle
accordingly, and try building again.
Gradle Version:
gradle-wrapper.properties
file:distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip // Or a more recent version
And your build.gradle
(project level):
dependencies {
classpath "com.android.tools.build:gradle:7.0.4" // Or a more recent version
}
Update these to the latest stable versions and try again. Sync your Gradle project after making changes.
Invalid Characters in Passwords:
!@#$%^&*()
) in your passwords, especially if you're using environment variables or if your shell might interpret them differently. Stick to alphanumeric characters and a few safe symbols like _
and -
.Clean and Rebuild:
In VS Code, try:
Flutter: Clean Project
Flutter: Build APK
or Flutter: Build AAB
Or run these commands in the terminal:
flutter clean
flutter pub get
flutter build appbundle --release
Absolute Paths:
key.properties
or the environment variable is an absolute path (e.g., D:/path/to/keystore.jks
or /Users/yourname/path/to/keystore.jks
). Relative paths can sometimes cause problems.Invalid Characters on alias:
Debugging Tips
--stacktrace
to your Gradle command to get a more detailed error message.build.gradle
, you can temporarily print out the values of your variables to ensure they are being read correctly:android {
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
println "Store File: " + MYAPP_UPLOAD_STORE_FILE
println "Store Password: " + MYAPP_UPLOAD_STORE_PASSWORD
println "Key Alias: " + MYAPP_UPLOAD_KEY_ALIAS
println "Key Password: " + MYAPP_UPLOAD_KEY_PASSWORD
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
}
These println
statements will output the values to the console when you run the build. Remove them after debugging.
In Summary
The "Cannot recover key" error is almost always a credential problem. Go through the steps above meticulously. Pay special attention to the password checks. Switching to environment variables is highly recommended for security and can sometimes resolve path-related issues. Creating a new keystore is a good troubleshooting step if you suspect corruption. Good luck!