androidfluttergradlebuild.gradle

"Cannot recover key" while doing Flutter release. What I can do to solve this, please?


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:

  1. I'm using Visual Studio Code, not Eclipse
  2. I'm using Flutter
  3. I'm using Gradle
  4. I have used the same password in the storePassword and keyPassword
  5. I can check what my Alias is through terminal using the password registered in key.properties
  6. It is the first time I'm generating an aab for my app, it is not an update.

I hope it helps understand better my situation. Glad if you can help me!


Solution

  • 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

    1. 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
              }
          }
      }
      
      • Password Mismatch: This is the most common culprit. You said you used the same password, but double, triple, quadruple check. A single typo can cause this. A good test:
      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.

    2. 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
              }
          }
      }
      
      • Now, set environment variables corresponding to these values. For example:
      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.

    3. Keystore Corruption:

      • It's rare, but possible, that your keystore file itself is corrupted. Try creating a new keystore and key alias. Use the command:
      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.

    4. Gradle Version:

      • Sometimes, Gradle version incompatibilities can cause issues. Make sure your Gradle version and the Android Gradle Plugin version are compatible. Check your 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.

    5. Invalid Characters in Passwords:

      • Avoid using special characters (e.g., !@#$%^&*()) 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 -.
    6. 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
      
    7. Absolute Paths:

      • Ensure the path to your keystore in 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.
    8. Invalid Characters on alias:

      • Avoid using spaces or any special characters in your alias, stick with alphanumeric characters.

    Debugging Tips

    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!