apache/cordova-android · error · RuntimeException

Unable to determine Android SDK directory.

Error message

Unable to determine Android SDK directory.

What it means

getAndroidSdkDir resolves the Android SDK in priority order: ANDROID_HOME env var, ANDROID_SDK_ROOT env var, then local.properties at the project root (sdk.dir, or legacy android.dir resolved against rootDir — only consulted when no env var is set), then the android.home system property. If every source yields null, this RuntimeException is thrown. Note that a present-but-wrong env var is NOT this error — it produces a build-tools error later; this fires only when all four sources are absent.

Source

Thrown at framework/cordova.gradle:119

        Properties properties = new Properties()
        localProperties.withInputStream { instr ->
            properties.load(instr)
        }
        def sdkDirProp = properties.getProperty('sdk.dir')
        if (sdkDirProp != null) {
            androidSdkDir = sdkDirProp
        } else {
            sdkDirProp = properties.getProperty('android.dir')
            if (sdkDirProp != null) {
                androidSdkDir = (new File(rootDir, sdkDirProp)).getAbsolutePath()
            }
        }
    }
    if (androidSdkDir == null && systemProperty != null) {
        androidSdkDir = systemProperty
    }
    if (androidSdkDir == null) {
        throw new RuntimeException(
            "Unable to determine Android SDK directory.")
    }
    androidSdkDir
}

def doExtractIntFromManifest(name) {
    def manifestFile = file(android.sourceSets.main.manifest.srcFile)
    def pattern = Pattern.compile(name + "=\"(\\d+)\"")
    def matcher = pattern.matcher(manifestFile.getText())
    matcher.find()
    return new BigInteger(matcher.group(1))
}

def doGetConfigXml() {
    def xml = file("src/main/res/xml/config.xml").getText()
    // Disable namespace awareness since Cordova doesn't use them properly
    return new XmlParser(false, false).parseText(xml)
}

View on GitHub (pinned to 7c1e190064)

Solutions

  1. Create platforms/android/local.properties (or the repo-root local.properties for the framework build) containing sdk.dir=/absolute/path/to/android-sdk — use forward slashes on Windows or escape the backslashes and colon.
  2. Or export ANDROID_HOME (and ANDROID_SDK_ROOT) in the shell / CI environment pointing at the SDK root.
  3. Or pass it per invocation: ./gradlew -Dandroid.home=/path/to/sdk assembleDebug.
  4. On CI, prefer env vars, since local.properties is machine-specific and should not be committed.

Example fix

# before — no SDK source configured
$ ./gradlew assembleDebug
... Unable to determine Android SDK directory.

# after (option 1 — machine-local file)
$ printf 'sdk.dir=/opt/android-sdk\n' > platforms/android/local.properties
# after (option 2 — environment)
$ export ANDROID_HOME=/opt/android-sdk && ./gradlew assembleDebug
Defensive patterns

Strategy: validation

Validate before calling

# Verify an SDK source exists and points at a real SDK before building
SDK="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}"
if [ -z "$SDK" ] && [ -f platforms/android/local.properties ]; then
  SDK=$(sed -n 's/^sdk.dir=//p' platforms/android/local.properties | head -1)
fi
[ -n "$SDK" ] && [ -d "$SDK/build-tools" ] \
  || { echo 'No Android SDK location — export ANDROID_HOME or write sdk.dir to platforms/android/local.properties'; exit 1; }

Prevention

When it happens

Trigger: Building in a shell/CI job where neither ANDROID_HOME nor ANDROID_SDK_ROOT is exported; a fresh clone on a new machine — local.properties is deliberately .gitignored, so it does not exist; building the framework without passing -Dandroid.home.

Common situations: CI pipelines that install the SDK but forget to export ANDROID_HOME in the job step; new teammates' first build; scripts that sanitize the environment; Linux case mismatches in the env var value are a sibling problem (dir not found) rather than this one.

Related errors


AI-assisted analysis of apache/cordova-android@7c1e190064 (2026-08-22). Data as JSON: /api/errors/b609c63fe661314a. Report an issue: GitHub.