microg/GmsCore · error · RuntimeException

Initialization failed

Error message

Initialization failed

What it means

startSmsRetriever throws 'Initialization failed' when ensureReady(arrayOf(RECEIVE_SMS)) returns false — i.e. the RECEIVE_SMS permission could not be granted (or the SDK check passed but permission acquisition failed). ensureReady returns false rather than throwing when ensurePermission fails, and the caller converts that into a RuntimeException.

Source

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

                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,
            packageName = packageName,
            appHashString = appHashString,
            timeoutPendingIntent = getTimeoutPendingIntent(context, packageName)
        )
        requests[request.id] = request
        alarmManager.set(AlarmManager.RTC, request.creation + TIMEOUT, request.timeoutPendingIntent)
    }

    suspend fun startWithConsentPrompt(packageName: String, senderPhoneNumber: String?) {
        if (!ensureReady(arrayOf(RECEIVE_SMS, READ_CONTACTS)))

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Declare <uses-permission android:name="android.permission.RECEIVE_SMS"/> in AndroidManifest.xml
  2. Request RECEIVE_SMS at runtime with ActivityCompat.requestPermissions before calling startSmsRetriever
  3. Check ContextCompat.checkSelfPermission(this, RECEIVE_SMS) == PERMISSION_GRANTED beforehand and handle denial gracefully
  4. Consider the SMS User Consent API or SMS Retriever via Play Services so RECEIVE_SMS is not needed

Example fix

// before
scope.launch { core.startSmsRetriever(packageName) }
// after
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED) {
    scope.launch { core.startSmsRetriever(packageName) }
} else {
    ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.RECEIVE_SMS), REQ)
}
Defensive patterns

Strategy: validation

Validate before calling

val granted = ContextCompat.checkSelfPermission(ctx, Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED

Try / catch

try { core.startSmsRetriever(pkg) } catch (e: RuntimeException) { if (e.message == "Initialization failed") requestPermissions(arrayOf(RECEIVE_SMS), REQ) else throw e }

Prevention

When it happens

Trigger: Calling startSmsRetriever() when the calling app has not been granted android.permission.RECEIVE_SMS and the library cannot obtain it (permission not declared in the app manifest, or user has denied it).

Common situations: Forgetting to declare RECEIVE_SMS in AndroidManifest.xml; user revoked the permission in Settings; targeting Android 6.0+ where permissions must be granted at runtime and the app never requested them.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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