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.

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.

Appendix: 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)