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
- Raise the device to Android 4.4 (API 19) or newer, or test on a modern emulator image
- Set minSdkVersion >= 19 in the consuming app so the code path is unreachable on old devices
- Guard the call at runtime with Build.VERSION.SDK_INT check before invoking the retriever
- 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
- Set minSdkVersion >= 19 in your app
- Check Build.VERSION.SDK_INT before any SMS retriever call
- Provide a manual OTP-entry fallback for old devices
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
- Initialization failed
- Collision in hash string, can't use SMS Retriever API
- App already listening
- No signature found for $packageName
- deleteAll was set to true but keys were also provided
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/87c530043ea7a64c.
Report an issue: GitHub.