termux/termux-app · error · GradleException
Unsupported TERMUX_PACKAGE_VARIANT "%s"
Error message
Unsupported TERMUX_PACKAGE_VARIANT "%s"
What it means
This GradleException is thrown by the `downloadBootstraps` task in app/build.gradle when the `TERMUX_PACKAGE_VARIANT` environment variable resolves to a value other than the two recognized variants (`apt-android-7` or `apt-android-5`). The variant selects which prebuilt bootstrap zip (apt package set) is downloaded and bundled into the APK, so an unknown variant has no corresponding checksums or download URLs and the build cannot proceed safely. It fails the build immediately rather than silently bundling the wrong bootstrap, which would crash the app at startup (TermuxBootstrap.setTermuxPackageManagerAndVariant throws a RuntimeException for unknown variants).
Source
Thrown at app/build.gradle:234
}
task downloadBootstraps() {
doLast {
def packageVariant = project.ext.packageVariant
if (packageVariant == "apt-android-7") {
def version = "2026.02.12-r1" + "%2B" + "apt.android-7"
downloadBootstrap("aarch64", "ea2aeba8819e517db711f8c32369e89e7c52cee73e07930ff91185e1ab93f4f3", version)
downloadBootstrap("arm", "a38f4d3b2f735f83be2bf54eff463e86dc32a3e2f9f861c1557c4378d249c018", version)
downloadBootstrap("i686", "f5bc0b025b9f3b420b5fcaeefc064f888f5f22a0d6fd7090f4aac0c33eb3555b", version)
downloadBootstrap("x86_64", "b7fd0f2e3a4de534be3144f9f91acc768630fc463eaf134ab2e64c545e834f7a", version)
} else if (packageVariant == "apt-android-5") {
def version = "2022.04.28-r6" + "+" + packageVariant
downloadBootstrap("aarch64", "913609d439415c828c5640be1b0561467e539cb1c7080662decaaca2fb4820e7", version)
downloadBootstrap("arm", "26bfb45304c946170db69108e5eb6e3641aad751406ce106c80df80cad2eccf8", version)
downloadBootstrap("i686", "46dcfeb5eef67ba765498db9fe4c50dc4690805139aa0dd141a9d8ee0693cd27", version)
downloadBootstrap("x86_64", "615b590679ee6cd885b7fd2ff9473c845e920f9b422f790bb158c63fe42b8481", version)
} else {
throw new GradleException("Unsupported TERMUX_PACKAGE_VARIANT \"" + packageVariant + "\"")
}
}
}
afterEvaluate {
android.applicationVariants.all { variant ->
variant.javaCompileProvider.get().dependsOn(downloadBootstraps)
}
}
View on GitHub (pinned to 3df69d1da1)
Solutions
- Check the current value: run `echo "$TERMUX_PACKAGE_VARIANT"` in the build shell. If it is empty, unset it with `unset TERMUX_PACKAGE_VARIANT` so the Groovy Elvis operator falls back to the default `apt-android-7`.
- If you intentionally set the variable, correct it to one of the two supported values: `export TERMUX_PACKAGE_VARIANT=apt-android-7` (API 24+, default) or `export TERMUX_PACKAGE_VARIANT=apt-android-5` (legacy API 21+).
- In CI, audit the pipeline/secret that injects `TERMUX_PACKAGE_VARIANT` and align it with a supported value, or remove the injection entirely to use the default.
- If you are adding a genuinely new variant, update three places in lockstep: the `if/else` chain in `downloadBootstraps` (add a branch with download URLs + SHA-256 checksums), the Java enum in `com.termux.shared.termux.TermuxBootstrap.PackageVariant`, and the documentation comment listing supported values at app/build.gradle:11.
Example fix
// before export TERMUX_PACKAGE_VARIANT="apt-android-8" ./gradlew assembleRelease // after unset TERMUX_PACKAGE_VARIANT # or: export TERMUX_PACKAGE_VARIANT=apt-android-7 ./gradlew assembleRelease
Defensive patterns
Strategy: validation
Validate before calling
// Pre-build check (Groovy, in app/build.gradle ext block or a CI script)
def packageVariant = System.getenv("TERMUX_PACKAGE_VARIANT") ?: "apt-android-7"
def supported = ["apt-android-7", "apt-android-5"] as Set
if (!(packageVariant in supported)) {
throw new GradleException(
"Unsupported TERMUX_PACKAGE_VARIANT \"" + packageVariant + "\". " +
"Supported: " + supported.join(", ") + ". " +
"Unset the env var to use the default, or fix the value.")
} Type guard
// Shell guard — call before invoking gradle
check_variant() {
local v="${TERMUX_PACKAGE_VARIANT:-apt-android-7}"
case "$v" in
apt-android-7|apt-android-5) return 0 ;;
"") return 0 ;; # treat truly-unset as OK (Elvis handles it)
*) echo "Unsupported TERMUX_PACKAGE_VARIANT: '$v'" >&2; return 1 ;;
esac
} Try / catch
// Gradle task wrapping the variant check
task checkPackageVariant() {
doLast {
def v = project.ext.packageVariant
try {
assert v in ["apt-android-7", "apt-android-5"]
} catch (AssertionError e) {
throw new GradleException("Unsupported TERMUX_PACKAGE_VARIANT \"${v}\". Set it to apt-android-7 or apt-android-5, or unset it.")
}
}
}
downloadBootstraps.dependsOn checkPackageVariant Prevention
- Never export TERMUX_PACKAGE_VARIANT globally; set it per-build-command or per-CI-job so stale values cannot leak in.
- If you rely on the default, explicitly `unset TERMUX_PACKAGE_VARIANT` at the top of CI scripts to neutralize inherited empty-string exports that bypass the Groovy Elvis fallback.
- Keep the Gradle if/else chain, the Java PackageVariant enum, and the supported-values doc comment in app/build.gradle as a single atomic change unit — a drift between them is the most common source of this error during variant refactors.
- Add a build-time assertion that runs before downloadBootstraps so an invalid variant fails with an actionable message instead of downloading the wrong archive.
- Pin the supported-variant list in one place (a shared constant or generated file) and have both Gradle and Java reference it, eliminating manual sync.
When it happens
Trigger: The error triggers when (a) `TERMUX_PACKAGE_VARIANT` is exported in the shell/CI environment to a typo'd or unsupported string (e.g. `apt-adroid-7`, `apt-android-8`, `pacman-android-7`), or (b) the variable is set to an empty string (`TERMUX_PACKAGE_VARIANT=""`), since the Groovy Elvis operator `?:` only falls back to the default when the env var is unset, not when it is empty. It also triggers if a new variant is introduced in the Java side (TermuxBootstrap.PackageVariant) but the Gradle if/else chain is not updated with matching download entries.
Common situations: Typical contexts: a developer copies a build command from an outdated wiki that references a variant that was removed or renamed; a CI pipeline inherits `TERMUX_PACKAGE_VARIANT` from a global secret/template with a stale value; someone experiments with the pacman-based variant naming before Gradle support is added; an empty-string export (`export TERMUX_PACKAGE_VARIANT=`) defeats the Elvis default and lands in the else branch.
Related errors
- Unsupported TERMUX_APP_PACKAGE_VARIANT "%s"
- Unsupported TERMUX_APP_PACKAGE_MANAGER "%s" with variant "%s
- Both key and macro can't be set for the same key. key: "%s",
- All keys have to specify either key or macro
- An key in the extra-key matrix must be a string or an object
AI-assisted analysis of termux/termux-app@3df69d1da1 (2026-08-13).
Data as JSON: /api/errors/2bf22c8b47e09e30.
Report an issue: GitHub.