Android APK Unsigned Build Error Fix
In this tutorial, you'll learn about Android APK Unsigned Build Error Fix. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Your Android build produces an unsigned APK with APK is not signed or INSTALL_PARSE_FAILED_NO_CERTIFICATES — the APK was built without a signing configuration, preventing installation on devices or upload to Google Play.
Step-by-Step Fix
1. Generate a keystore
# Wrong: no keystore available
# Right: generate a new keystore
keytool -genkey -v \
-keystore my-release-key.jks \
-keyalg RSA \
-keysize 2048 \
-validity 10000 \
-alias my-key-alias
Expected output:
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: John Doe
...
Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days
2. Configure Gradle signing
// android/app/build.gradle
// Wrong: no signing configuration
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
// Right: add signing configuration
android {
signingConfigs {
release {
storeFile file("my-release-key.jks")
storePassword "your-store-password"
keyAlias "my-key-alias"
keyPassword "your-key-password"
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
3. Use environment variables for keystore passwords
// android/app/build.gradle
// More secure: do not hardcode passwords
android {
signingConfigs {
release {
storeFile file(System.getenv("KEYSTORE_PATH") ?: "my-release-key.jks")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS") ?: "my-key-alias"
keyPassword System.getenv("KEY_PASSWORD")
}
}
}
# Set environment variables before building
export KEYSTORE_PATH="/path/to/my-release-key.jks"
export KEYSTORE_PASSWORD="your-store-password"
export KEY_ALIAS="my-key-alias"
export KEY_PASSWORD="your-key-password"
# Build the release APK
./gradlew assembleRelease
4. Build the signed APK
# Clean build
./gradlew clean
# Build release APK with signing
./gradlew assembleRelease
# Build Android App Bundle (AAB) for Play Store
./gradlew bundleRelease
5. Verify the APK signature
# Check if the APK is signed
jarsigner -verify -verbose -certs app-release.apk
# Expected output shows "jar verified" with no warnings
# Or use apksigner
/usr/local/android-sdk/build-tools/34.0.0/apksigner verify --verbose app-release.apk
Expected successful output:
Verifies
Verified using v1 scheme (JAR signing): true
Verified using v2 scheme (APK Signature Scheme v2): true
Verified using v3 scheme (APK Signature Scheme v3): true
Number of signers: 1
6. Fix v1/v2 signature scheme issues
// android/app/build.gradle
android {
signingConfigs {
release {
// Ensure both v1 and v2 signing are enabled
// v1 is required for Android < 7.0
// v2 is required for Android 7.0+
enableV1Signing true
enableV2Signing true
enableV3Signing true
}
}
}
7. Use Android Studio guided signing
# In Android Studio:
# Build > Generate Signed Bundle / APK...
# Select APK or Android App Bundle
# Provide keystore path and credentials
# Select release build variant
# Click Finish
Prevention
- Keep the keystore file in a secure location and back it up — losing it prevents app updates.
- Use environment variables or a secrets manager for keystore passwords in CI/CD.
- Use Android App Bundle (AAB) format for Google Play distribution.
- Verify APK signature with
jarsignerorapksignerafter every release build. - Test the signed APK on a device with
adb install app-release.apk.
Common Mistakes with apk signed
- Forgetting
deriving (Show, Eq)on custom data types needed for debugging - Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
- Using
headandtailinstead of pattern matching, causing runtime errors on empty lists
These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro