Tencent/matrix · error · GradleException
need sign apk but apksigner not found!
Error message
need sign apk but apksigner not found!
What it means
When `removeUnusedResources` is configured to re-sign the processed APK (`needSign = true`), the task must run apksigner to sign the rebuilt APK. This error is thrown when the configured `apksigner` value is null or empty, meaning no signer tool path was provided at all. It is a fail-fast configuration check performed before any work is done.
Solutions
- Set `apksigner` in the matrix removeUnusedResources extension to the full path of the apksigner binary, e.g. `$ANDROID_HOME/build-tools/34.0.0/apksigner`.
- Verify build-tools are installed via the SDK manager and use that version's path.
- If signing is handled elsewhere, disable it by setting `needSign = false` so the check is skipped.
Example fix
// before
matrix {
removeUnusedResources {
needSign = true
}
}
// after
matrix {
removeUnusedResources {
needSign = true
apksigner = "/opt/android-sdk/build-tools/34.0.0/apksigner"
}
} Defensive patterns
Strategy: validation
Validate before calling
def apksigner = "/opt/android-sdk/build-tools/34.0.0/apksigner"
assert apksigner?.trim() : 'apksigner path must be set when needSign=true'
matrix { removeUnusedResources { needSign = true; apksigner = apksigner } } Type guard
def hasApksigner = { String p -> p != null && !p.trim().isEmpty() } Try / catch
try { matrixRemoveUnusedResources() } catch (GradleException e) { if (e.message.contains('apksigner not found')) { ... configure apksigner ... } else throw e } Prevention
- Always set apksigner alongside needSign = true.
- Derive the path from ANDROID_HOME + build-tools version instead of hardcoding.
- Verify signing needs before enabling needSign.
When it happens
Trigger: `needSign` is true but the extension's `apksigner` property was never set (empty/null) when `removeUnusedResources` runs via `removeResources`.
Common situations: Enabling signing in matrixTrace/matrix config without pointing `apksigner` at `<Android SDK>/build-tools/<version>/apksigner`; using defaults on a machine without Android build-tools; copying sample config that omits the field.
Understand the failure class
Background: "missing required config value" errors: why libraries refuse to start when a configuration key is empty, unset, or blank — this error's family across 48 libraries.
Related errors
- need sign apk but signingConfig not found!
- Need signing apk but the path of apksigner is not specified!
- Need signing apk but signingConfig is not specified!
- apksigner returned with status: $ret
- need sign apk but apksigner $apksigner was not exist!
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/25ed4a3975e3b627.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-gradle-plugin/src/main/kotlin/com/tencent/matrix/plugin/task/RemoveUnusedResourcesTask.kt:128
val index = typeName.indexOf('-')
if (index >= 0) {
typeName = typeName.substring(0, index)
}
resourceName = "R.$typeName.$resName"
}
}
return resourceName
}
private fun removeUnusedResources(
originalApk: String,
rTxtFile: String,
signingConfig: SigningConfig?) {
// Check configurations
if (needSign) {
if (Util.isNullOrNil(apksigner)) {
throw GradleException("need sign apk but apksigner not found!");
} else if (!File(apksigner).exists()) {
throw GradleException("need sign apk but apksigner $apksigner was not exist!");
} else if (signingConfig == null) {
throw GradleException("need sign apk but signingConfig not found!");
}
}
var zipOutputStream: ZipOutputStream? = null
try {
try {
val inputFile = File(originalApk)
for (res in ignoreRes) {
ignoreResources.add(Util.globToRegexp(res))
}
val iterator = unusedResources.iterator()View on GitHub (pinned to 3b8293bd65)