microg/GmsCore · error · RuntimeException

No signature found for $packageName

Error message

No signature found for $packageName

What it means

getHashString throws 'No signature found for $packageName' when PackageManager.getSignatures(packageName) returns no signatures for the given package. The SMS Retriever hash (the 11-char string embedded in SMS messages) is computed from the package name plus its signing certificate; without a signature the hash cannot be derived.

Source

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

                    Log.w(TAG, "Error handling incoming SMS", e)
                }
            }
        }
    }

    private inner class TimeoutReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val requestId = intent.getIntExtra(EXTRA_REQUEST_ID, -1)
            if (requestId != -1) {
                handleTimeout(requestId)
            }
        }
    }

    @TargetApi(19)
    fun getHashString(packageName: String): String {
        val signature =
            context.packageManager.getSignatures(packageName).firstOrNull()?.toCharsString() ?: throw RuntimeException("No signature found for $packageName")
        val appInfo = "$packageName $signature"
        val messageDigest = MessageDigest.getInstance("SHA-256")
        messageDigest.update(appInfo.toByteArray(StandardCharsets.UTF_8))
        return Base64.encodeToString(messageDigest.digest(), Base64.NO_PADDING or Base64.NO_WRAP).substring(0, 11)
    }

    private fun anyOtherPackageHasHashString(packageName: String, hashString: String): Boolean {
        val collision = context.packageManager.getInstalledPackages(0)
            .firstOrNull { it.packageName != packageName && getHashString(it.packageName) == hashString } ?: return false

        Log.w(TAG, "Hash string collision between $packageName and ${collision.packageName} (both are $hashString)")
        return true
    }

    private fun isPhoneNumberInContacts(context: Context, phoneNumber: String): Boolean {
        fun normalizePhoneNumber(input: String): String {
            var output = ""
            if (!TextUtils.isEmpty(input)) {

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Pass the calling app's own packageName (context.packageName), not a hard-coded or wrong id
  2. Ensure the app is fully installed before computing the hash
  3. On Android 11+, add the correct <queries> declaration or QUERY_ALL_PACKAGES so the package and its signatures are visible
  4. Wrap in try-catch and fall back to Play Services' SmsRetriever.getClient(...).startSmsRetriever() which handles hashing itself

Example fix

// before
val name = "com.example.wrongid"
core.startSmsRetriever(name)
// after
val name = context.packageName
core.startSmsRetriever(name)
Defensive patterns

Strategy: validation

Validate before calling

try { context.packageManager.getPackageInfo(context.packageName, 0) } catch (e: PackageManager.NameNotFoundException) { /* not installed */ }

Try / catch

try { core.startSmsRetriever(pkg) } catch (e: RuntimeException) { if (e.message?.startsWith("No signature found") == true) usePlayServicesRetriever() else throw e }

Prevention

When it happens

Trigger: Calling startSmsRetriever() or anyOtherPackageHasHashString() for a packageName that is not installed, is an instant/incremental app without exposed signatures, or whose signatures are unavailable to the caller (e.g. querying another app's signatures without the QUERY_ALL_PACKAGES / <queries> visibility on Android 11+).

Common situations: Typo'd or wrong applicationId passed to startSmsRetriever; calling before the app's first install completes; Android 11+ package visibility filtering hiding the target package; installing via incremental/APK-split mechanisms where signature query returns empty.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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