microg/GmsCore · error · RuntimeException

Version not supported

Error message

Version not supported

What it means

ensureReady() in SmsRetrieverCore throws this RuntimeException when the device runs Android with SDK_INT below 19 (Android 4.4 KitKat). The SMS Retriever API depends on APIs introduced in API 19 (e.g. PackageManager signature hashing and SMS broadcast support), so the library hard-fails instead of silently degrading.

Source

Thrown at play-services-auth-api-phone/core/src/main/kotlin/org/microg/gms/auth/phone/SmsRetrieverCore.kt:89

    @TargetApi(19)
    private fun configureBroadcastListenersIfNeeded() {
        synchronized(this) {
            if (!this::timeoutBroadcastReceiver.isInitialized) {
                val intentFilter = IntentFilter(ACTION_SMS_RETRIEVE_TIMEOUT)
                timeoutBroadcastReceiver = TimeoutReceiver()
                ContextCompat.registerReceiver(context, timeoutBroadcastReceiver, intentFilter, ContextCompat.RECEIVER_NOT_EXPORTED)
            }
            if (!this::smsBroadcastReceiver.isInitialized) {
                val intentFilter = IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)
                intentFilter.priority = 999
                smsBroadcastReceiver = SmsReceiver()
                context.registerReceiver(smsBroadcastReceiver, intentFilter)
            }
        }
    }

    private suspend fun ensureReady(permissions: Array<String>): Boolean {
        if (SDK_INT < 19) throw RuntimeException("Version not supported")
        if (!ensurePermission(permissions)) return false
        configureBroadcastListenersIfNeeded()
        return true
    }

    suspend fun startSmsRetriever(packageName: String) {
        val appHashString = getHashString(packageName)

        if (!ensureReady(arrayOf(RECEIVE_SMS)))
            throw RuntimeException("Initialization failed")
        if (anyOtherPackageHasHashString(packageName, appHashString))
            throw RuntimeException("Collision in hash string, can't use SMS Retriever API")
        if (requests.values.any { it.packageName == packageName && it.appHashString == appHashString && it.type == RETRIEVER })
            throw RuntimeException("App already listening")

        val request = SmsRetrieverRequest(
            id = requestIdCounter.incrementAndGet(),
            type = RETRIEVER,

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Raise the device to Android 4.4 (API 19) or newer, or test on a modern emulator image
  2. Set minSdkVersion >= 19 in the consuming app so the code path is unreachable on old devices
  3. Guard the call at runtime with Build.VERSION.SDK_INT check before invoking the retriever
  4. Use a different SMS verification mechanism (e.g. user-typed code) on legacy devices

Example fix

// before
smsRetrieverCore.startSmsRetriever(packageName)
// after
if (Build.VERSION.SDK_INT >= 19) {
    smsRetrieverCore.startSmsRetriever(packageName)
} else {
    // fall back to manual SMS code entry
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (Build.VERSION.SDK_INT < 19) { /* skip / fallback */ }

Type guard

fun isSmsRetrieverSupported(): Boolean = Build.VERSION.SDK_INT >= 19

Try / catch

try { core.startSmsRetriever(pkg) } catch (e: RuntimeException) { if (e.message == "Version not supported") fallbackToManualCode() else throw e }

Prevention

When it happens

Trigger: Calling startSmsRetriever() or startWithConsentPrompt() (both delegate to ensureReady) on a device/emulator running API level 18 or lower.

Common situations: Testing on an old emulator AVD image or a legacy physical device below Android 4.4; minSdk left too low in the app so old devices can install the app and reach this code path.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/87c530043ea7a64c. Report an issue: GitHub.