Skip to content
Latchkey

Flutter "Keystore file not found" release signing in CI

The Android release build resolves signingConfigs.release and cannot find the .jks/.keystore file at the path in key.properties. The file is gitignored, so CI must materialize it from a secret before the build.

What this error means

The Gradle build fails with "Keystore file '/path/upload-keystore.jks' not found for signing config 'release'." during assembleRelease or bundleRelease.

Gradle
Execution failed for task ':app:validateSigningRelease'.
> Keystore file '/home/runner/work/app/app/android/app/upload-keystore.jks'
  not found for signing config 'release'.

Common causes

The keystore is not present in CI

The signing keystore is correctly excluded from version control, so a fresh checkout has no file at the configured path.

key.properties path does not match the runner layout

A relative storeFile resolves differently in CI than locally, so Gradle looks in the wrong place.

How to fix it

Decode the keystore from a secret

  1. Base64-encode the keystore and store it as a secret.
  2. Decode it into the path your key.properties expects before the build.
  3. Write key.properties with passwords from secrets in the same step.
.github/workflows/ci.yml
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > android/app/upload-keystore.jks

Use an absolute or workspace-relative storeFile

Resolve the keystore path against the project so local and CI layouts agree.

android/key.properties
storeFile=${rootProject.projectDir}/app/upload-keystore.jks

How to prevent it

  • Keep keystores out of git and inject them from secrets.
  • Materialize the keystore before any release Gradle task.
  • Use a consistent, project-relative storeFile path.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →