When building, installing, or distributing a Release APK from Android Studio, you may encounter “The APK is not signed” or another message indicating that the package does not contain a valid Android signature.
The APK is not signed APK is not signed ERROR: JAR_SIG_NO_SIGNATURES DOES NOT VERIFY
Android requires APKs to be digitally signed before they can be installed or updated on a device. Google’s current Android documentation states that all APKs must be signed with a certificate before installation or update. :contentReference[oaicite:18]{index=18}
The error commonly appears when the Release build type has no SigningConfig, an app-release-unsigned.apk artifact is being used, a manually generated APK was never signed, or the APK was modified after signing.
Google’s current Android build documentation also states that Gradle does not sign a Release APK or AAB unless a signing configuration is explicitly defined for that build. :contentReference[oaicite:19]{index=19}
This article explains how to diagnose and fix “The APK is not signed” using Android Studio, Gradle SigningConfig, apksigner, and keystore verification.
- What Does “The APK is not signed” Mean?
- Common Situations
- Common Causes
- 1. The Release Build Type Has No SigningConfig
- 2. You Are Using app-release-unsigned.apk
- 3. The Keystore Exists but Is Not Configured
- 4. SigningConfig Exists but Is Not Assigned to Release
- 5. A Manually Built APK Was Never Signed
- 6. The APK Was Modified After Signing
- 7. CI/CD Does Not Receive the Signing Secrets
- 8. The Wrong Build Variant Is Being Built
- 9. External Signing Properties Are Not Being Loaded
- Step 1: Verify the APK with apksigner
- Step 2: Check the APK Filename
- Step 3: Check the Release Signing Configuration
- Solution 1: Configure Release Signing with Kotlin DSL
- Solution 2: Configure Release Signing with Groovy
- Solution 3: Generate a Signed APK from Android Studio
- Solution 4: Create a Keystore If You Do Not Have One
- Solution 5: Sign an Unsigned APK with apksigner
- Solution 6: Specify the Key Alias
- Solution 7: Verify the Keystore
- Solution 8: Fix the Missing Release Assignment
- Solution 9: Check Environment Variables
- Solution 10: Check keystore.properties
- Solution 11: Do Not Commit Real Signing Passwords
- Solution 12: Select the Correct Build Variant
- Solution 13: Rebuild the Release APK
- Solution 14: Verify Every Output Artifact
- Solution 15: Use the Correct zipalign and Signing Order
- Solution 16: Do Not Repack the APK After Signing
- Solution 17: Verify the Keystore in CI/CD
- Solution 18: Verify the APK at the End of CI/CD
- Why Does a Debug APK Install Normally?
- Should You Sign a Production APK with the Debug Key?
- Fastest Way to Check Whether an APK Is Signed
- Difference Between “The APK is not signed” and “APK signature verification failed”
- An APK Can Be Signed but Still Fail to Update an Existing App
- Check the APK Signing Certificate
- If You Use Google Play App Signing
- Fastest Troubleshooting Order
- If the Problem Still Occurs
- Summary
What Does “The APK is not signed” Mean?
An APK requires a digital signature created with a developer-controlled private key.
The signature helps Android:
- Identify the signer of the APK
- Detect changes made after signing
- Confirm update continuity between versions of an app
- Support signature-based Android security features
Android application certificates do not normally need to be issued by a public certificate authority. Developers commonly use certificates associated with their own private signing keys. :contentReference[oaicite:20]{index=20}
Best first step: Verify the APK itself before changing Gradle caches, ADB, or Android Studio settings.
Common Situations
- Building a Release APK
- Exporting an APK from Android Studio
- Running
assembleRelease - Installing a manually built APK through adb
- Uploading an APK to another app store
- Removing a signing configuration
- Moving the project to another computer
- Editing
build.gradle.ktsorbuild.gradle - Generating a Release APK in CI/CD
- Repacking or modifying an APK after signing
Common Causes
1. The Release Build Type Has No SigningConfig
This is the most common cause.
Google’s current Android documentation states that Gradle does not sign Release APKs or AABs unless you explicitly define a signing configuration. :contentReference[oaicite:21]{index=21}
For example:
buildTypes { getByName("release") { isMinifyEnabled = false } }
does not configure Release signing.
2. You Are Using app-release-unsigned.apk
Some build workflows generate an artifact named:
app-release-unsigned.apk
This file requires a separate signing step before installation or distribution.
3. The Keystore Exists but Is Not Configured
Merely having a keystore file on the computer does not sign a Release build.
Gradle needs values such as:
storeFile storePassword keyAlias keyPassword
and the signing configuration must be assigned to the Release build type. :contentReference[oaicite:22]{index=22}
4. SigningConfig Exists but Is Not Assigned to Release
This alone is not enough:
signingConfigs { create("release") { ... } }
The Release build also needs:
signingConfig = signingConfigs.getByName("release")
5. A Manually Built APK Was Never Signed
If Android Studio or Gradle signing automation is not being used, the APK must be signed separately, normally with Android SDK Build Tools.
6. The APK Was Modified After Signing
Repacking, editing, or adding content after signing can invalidate the signature.
APK Signature Scheme v2 and later protect APK content in a way that makes post-signing modification invalidate the signature. Google’s Android tooling documentation has explicitly documented this behavior. :contentReference[oaicite:23]{index=23}
7. CI/CD Does Not Receive the Signing Secrets
If local Release builds are signed but CI output is unsigned, the remote environment may be missing the keystore or required secrets.
8. The Wrong Build Variant Is Being Built
Projects using product flavors may have several Release-like variants, and the signing configuration may not be applied to the one being built.
9. External Signing Properties Are Not Being Loaded
If the build reads the keystore location and passwords from environment variables or a local properties file, missing values can prevent the Release signing configuration from being completed.
Step 1: Verify the APK with apksigner
Run:
apksigner verify app-release.apk
For detailed information:
apksigner verify --verbose --print-certs app-release.apk
An unsigned APK will fail signature verification.
Step 2: Check the APK Filename
Inspect:
app/build/outputs/apk/release/
If the artifact is named:
app-release-unsigned.apk
it is normally intended to be signed separately.
Step 3: Check the Release Signing Configuration
Open the module-level build.gradle.kts or build.gradle.
Confirm both of these:
- A Release entry exists under
signingConfigs. - The Release build type uses that signing configuration.
Solution 1: Configure Release Signing 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")
}
}
}
Google’s current documentation uses this same structure: create the Release SigningConfig and assign it to the Release build type. :contentReference[oaicite:24]{index=24}
Solution 2: Configure Release Signing with Groovy
android { signingConfigs { release { storeFile file("release.jks") storePassword "STORE_PASSWORD" keyAlias "release" keyPassword "KEY_PASSWORD" } }
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
Rebuild the Release APK afterward.
Solution 3: Generate a Signed APK from Android Studio
Open:
Build → Generate Signed App Bundle or APK
Select APK and provide:
- Key store path
- Key store password
- Key alias
- Key password
Google’s current release-preparation documentation explains that Android Studio and Gradle can automate creation of a Release APK signed with your private key. :contentReference[oaicite:25]{index=25}
Solution 4: Create a Keystore If You Do Not Have One
Android Studio can create a new upload key and keystore from the signed-build workflow.
After creation, keep the keystore and private key in a secure location and maintain reliable backups.
Google explicitly warns developers to keep signing keys secure and backed up. :contentReference[oaicite:26]{index=26}
Solution 5: Sign an Unsigned APK with apksigner
For an unsigned APK:
apksigner sign --ks release.jks app-release-unsigned.apk
To preserve the original file:
apksigner sign --ks release.jks --out app-release.apk app-release-unsigned.apk
Then verify:
apksigner verify --verbose --print-certs app-release.apk
Solution 6: Specify the Key Alias
If the keystore contains multiple keys:
apksigner sign \ --ks release.jks \ --ks-key-alias release \ --out app-release.apk \ app-release-unsigned.apk
Find the actual alias with:
keytool -list -v -keystore release.jks
Solution 7: Verify the Keystore
keytool -list -v -keystore release.jks
Check:
- Store password
- Key alias
- Certificate information
- SHA-256 fingerprint
Make sure the keystore belongs to the intended application.
Solution 8: Fix the Missing Release Assignment
This only creates a configuration:
signingConfigs { create("release") { ... } }
You also need:
buildTypes { getByName("release") { signingConfig = signingConfigs.getByName("release") } }
This is the pattern currently documented by Google. :contentReference[oaicite:27]{index=27}
Solution 9: Check Environment Variables
Google’s current Android build documentation recommends avoiding plaintext signing passwords in build files and shows loading them from environment variables. :contentReference[oaicite:28]{index=28}
Kotlin DSL:
storePassword = System.getenv("KSTOREPWD") keyPassword = System.getenv("KEYPWD")
macOS or Linux:
printenv KSTOREPWD printenv KEYPWD
Windows PowerShell:
$env:KSTOREPWD $env:KEYPWD
Security: Do not print real signing passwords into CI logs merely to test whether secrets are configured.
Solution 10: Check keystore.properties
Example:
storeFile=/Users/user/AndroidKeys/release.jks storePassword=STORE_PASSWORD keyAlias=release keyPassword=KEY_PASSWORD
Verify:
- The file exists.
- The keystore path is correct.
- The alias is correct.
- No accidental whitespace exists in the values.
- The Release build actually loads the file.
Solution 11: Do Not Commit Real Signing Passwords
Hard-coded values such as:
storePassword = "password" keyPassword = "password"
are technically possible but should not be committed to a public or shared repository.
Google’s current documentation explicitly recommends keeping Release signing passwords out of the build file and using environment variables or local secret properties instead. :contentReference[oaicite:29]{index=29}
Solution 12: Select the Correct Build Variant
Projects with product flavors can have variants such as:
freeDebug freeRelease paidDebug paidRelease
Verify that the intended Release variant receives the appropriate signing configuration.
Solution 13: Rebuild the Release APK
macOS or Linux:
./gradlew clean ./gradlew assembleRelease
Windows:
gradlew.bat clean gradlew.bat assembleRelease
With a correctly configured SigningConfig, the Release output should be signed.
Solution 14: Verify Every Output Artifact
Check:
app/build/outputs/apk/release/
Then run:
apksigner verify --verbose --print-certs APK_FILE
for the artifact you intend to distribute.
Solution 15: Use the Correct zipalign and Signing Order
For manual APK processing, use:
Build ↓ Required APK modifications ↓ zipalign ↓ apksigner sign ↓ apksigner verify
Do not perform content-changing operations after the final signing step.
Solution 16: Do Not Repack the APK After Signing
Avoid these post-signing operations:
- Adding files with a ZIP tool
- Directly modifying the manifest
- Replacing resources
- Recompressing the package
- Running content-changing CI post-processing
APK Signature Scheme v2 and later are invalidated by post-signing modifications to protected APK content. :contentReference[oaicite:30]{index=30}
Solution 17: Verify the Keystore in CI/CD
If CI reconstructs a keystore from Base64 or another secret format, test it immediately:
keytool -list -v -keystore release.jks
If this fails, fix keystore reconstruction before debugging APK signing.
Solution 18: Verify the APK at the End of CI/CD
Add a final validation step:
apksigner verify --verbose --print-certs app-release.apk
This helps prevent an unsigned APK from reaching the distribution stage.
Why Does a Debug APK Install Normally?
Android Studio automatically configures the Debug build type with a generic debug keystore.
Google’s current build-variant documentation states that Android Studio signs the Debug build with a generic debug keystore by default. :contentReference[oaicite:31]{index=31}
app-debug.apk → automatically signed app-release.apk → requires a Release SigningConfig
Common misconception: A working Debug APK does not prove that the Release APK is configured for signing.
Should You Sign a Production APK with the Debug Key?
Although a debug key can technically sign APKs in some development workflows, it should not be used as the long-term signing identity for a production Release app.
Use a properly managed Release key or upload key for distribution.
Fastest Way to Check Whether an APK Is Signed
apksigner verify --verbose --print-certs app-release.apk
If verification fails, investigate the signing configuration or post-signing modification process.
Difference Between “The APK is not signed” and “APK signature verification failed”
“The APK is not signed” more directly indicates that a usable signature is absent.
By contrast:
APK signature verification failed
can also occur when a signature exists but is invalid because the APK was modified or the signature structure is damaged.
An APK Can Be Signed but Still Fail to Update an Existing App
These are separate conditions:
APK is correctly signed ≠ APK uses the same signing identity as the installed app
If only update installation fails, compare the old and new signing certificates.
Check the APK Signing Certificate
apksigner verify --print-certs app-release.apk
Check the keystore as well:
keytool -list -v -keystore release.jks
Compare certificate information to confirm that the intended key was used.
If You Use Google Play App Signing
Google Play App Signing can separate the upload key controlled by the developer from the app signing key used by Google Play for distributed APKs.
Use the correct local signing or upload-key configuration for your Release artifact and protect the keystore carefully.
Google’s current Android documentation continues to emphasize secure keystore storage and secure backups. :contentReference[oaicite:32]{index=32}
Fastest Troubleshooting Order
- Run
apksigner verify --verbose --print-certs app.apk. - Check whether the filename contains
unsigned. - Verify that a Release SigningConfig exists.
- Verify that the Release build type uses it.
- Check the keystore and alias.
- Rebuild the Release APK.
- If necessary, sign the unsigned APK with
apksigner sign. - Immediately verify the final APK again.
If the Problem Still Occurs
Verify all of the following:
- You are using the intended Release APK.
- You are not using
app-release-unsigned.apk. - A Release SigningConfig exists.
- The SigningConfig is assigned to the Release build type.
- The correct keystore is being used.
- The key alias is correct.
- The store and key passwords are correct.
keystore.propertiesis actually loaded.- Required environment variables exist.
- CI/CD receives the keystore and secrets.
- The APK is not modified after signing.
- You verified the APK with
apksigner. - You are not building the wrong variant.
Summary
Android Studio “The APK is not signed” usually means that the Release APK does not contain a valid digital signature.
Android requires APKs to be signed before installation or update. :contentReference[oaicite:33]{index=33}
Start with:
apksigner verify --verbose --print-certs app-release.apk
If the APK is unsigned, configure Release signing:
signingConfigs { create("release") { storeFile = file("release.jks") storePassword = "STORE_PASSWORD" keyAlias = "release" keyPassword = "KEY_PASSWORD" } }
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
}
}
Google’s current Android documentation states that Release APKs and AABs are not signed by Gradle unless a signing configuration is explicitly defined and assigned to the Release build type. :contentReference[oaicite:34]{index=34}
If you already have an unsigned APK, sign it manually with:
apksigner sign --ks release.jks --out app-release.apk app-release-unsigned.apk
Then immediately verify it:
apksigner verify --verbose --print-certs app-release.apk
Finally, do not modify or repack the APK after signing, because post-signing changes can invalidate modern APK signatures. :contentReference[oaicite:35]{index=35}
