microg/GmsCore · error · IllegalStateException

API unavailable

Error message

API unavailable

What it means

GoogleCertificatesImpl.queryPackageSigned throws IllegalStateException("API unavailable") when fine-grained package signature verification is not available. The check delegates to isFineGrainedPackageVerificationAvailable, so this guard fires whenever that capability query returns false.

Source

Thrown at play-services-core/src/main/kotlin/com/google/android/gms/common/GoogleCertificatesImpl.kt:69

            query?.callingPackage == null -> false
            query.certData != null -> {
                isGooglePackage(query.callingPackage, query.certData) || (pm != null && pm.isPlatformCertificate(query.certData))
            }
            pm != null -> pm.getExtendedPackageInfo(query.callingPackage).isGoogleOrPlatformPackage
            else -> false
        }
    }

    override fun isPackageGoogleOrPlatformSigned(query: GoogleCertificatesLookupQuery): GoogleCertificatesLookupResponse {
        return certificateLookup(query, true)
    }

    override fun isPackageGoogleOrPlatformSignedAvailable(): Boolean {
        return true
    }

    override fun queryPackageSigned(query: GoogleCertificatesLookupQuery): GoogleCertificatesLookupResponse {
        if (!isFineGrainedPackageVerificationAvailable) throw IllegalStateException("API unavailable")
        return certificateLookup(query, false)
    }

    override fun isFineGrainedPackageVerificationAvailable(): Boolean {
        return true
    }

    private fun certificateLookup(query: GoogleCertificatesLookupQuery, allowPlatform: Boolean): GoogleCertificatesLookupResponse {
        val context = query.context
            ?: return GoogleCertificatesLookupResponse(false, "context is null", 5, 1)
        val packageManager = context.packageManager
            ?: return GoogleCertificatesLookupResponse(false, "context has no package manager", 5, 1)
        val callingPackage = query.callingPackage
            ?: return GoogleCertificatesLookupResponse(false, "callingPackage is null", 5, 1)
        val packageInfo = packageManager.getExtendedPackageInfo(callingPackage)
        if (!packageInfo.isInstalled)
            return GoogleCertificatesLookupResponse(false, "callingPackage not found", 4, 1)
        return if (packageInfo.isGooglePackage || (allowPlatform && packageInfo.isPlatformPackage)) {

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Check isFineGrainedPackageVerificationAvailable (or isPackageGoogleOrPlatformSignedAvailable) before calling queryPackageSigned
  2. Update microG to a current build where the fine-grained verification API is implemented
  3. Fall back to the non-fine-grained lookup path when the capability is unavailable
  4. Catch IllegalStateException around the lookup and degrade gracefully

Example fix

// before
val result = certs.queryPackageSigned(query)
// after
if (!certs.isFineGrainedPackageVerificationAvailable) {
    throw IllegalStateException("fine-grained verification not available")
}
val result = certs.queryPackageSigned(query)
Defensive patterns

Strategy: type-guard

Validate before calling

if (!certs.isFineGrainedPackageVerificationAvailable) {
    throw IllegalStateException("fine-grained verification unavailable")
}

Type guard

fun GoogleCertificatesLookup.canQueryFineGrained(): Boolean =
    isPackageGoogleOrPlatformSignedAvailable && isFineGrainedPackageVerificationAvailable

Try / catch

try {
    val result = certs.queryPackageSigned(query)
} catch (e: IllegalStateException) {
    // fall back to coarse lookup
}

Prevention

When it happens

Trigger: Calling queryPackageSigned(GoogleCertificatesLookupQuery) while isFineGrainedPackageVerificationAvailable returns false — in upstream Play services this happens when the Play services version lacks the fine-grained verification API; in microG it is normally always true, so hitting this means an unexpected state or modified build.

Common situations: Apps probing Google certificate verification on devices with mismatched or outdated Play services / microG builds, or forked builds where the capability override was changed to false.

Related errors


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