microg/GmsCore · error · IllegalStateException
Nothing cached: $cacheKey
Error message
Nothing cached: $cacheKey
What it means
InAppBillingServiceImpl.requestAuthProofToken looks up a previously cached buy-flow entry from buyFlowCacheMap using the caller-supplied cacheKey and throws this IllegalStateException when the key is absent. It means the auth-proof-token request was made without the buy flow first having stored its state under that key.
Source
Thrown at vending-app/src/main/java/org/microg/vending/billing/InAppBillingServiceImpl.kt:149
buyFlowCacheEntry.lastAcquireResult = coreResult
if (coreResult.acquireParsedResult.action?.droidGuardMap?.isNotEmpty() == true) {
DroidGuardClient.getResults(context, "phonesky_acquire_flow", coreResult.acquireParsedResult.action.droidGuardMap).addOnCompleteListener { task ->
buyFlowCacheEntry.droidGuardResult = task.result
}
}
coreResult.acquireParsedResult.purchaseItems.forEach {
PurchaseManager.addPurchase(buyFlowCacheEntry.account, buyFlowCacheEntry.packageName, it)
}
return BuyFlowResult(
coreResult.acquireParsedResult,
buyFlowCacheEntry.account,
coreResult.acquireParsedResult.result.toBundle()
)
}
fun requestAuthProofToken(context: Context, cacheKey: String, password: String): String {
val buyFlowCacheEntry = buyFlowCacheMap[cacheKey]
?: throw IllegalStateException("Nothing cached: $cacheKey")
val deferred = CoroutineScope(Dispatchers.IO).async {
createIAPCore(
context,
buyFlowCacheEntry.account,
buyFlowCacheEntry.packageName
).requestAuthProofToken(password)
}
return runBlocking { deferred.await() }
}
private fun createIAPCore(context: Context, account: Account, pkgName: String): IAPCore {
val key = "$pkgName:${account.name}"
val cacheEntry = iapCoreCacheMap[key]
if (cacheEntry != null) {
if (cacheEntry.expiredAt > System.currentTimeMillis())
return cacheEntry.iapCore
iapCoreCacheMap.remove(key)
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Perform the initial buy-intent/acquire flow that populates buyFlowCacheMap before requesting an auth proof token, and reuse the exact key it returned.
- Persist or re-acquire the cache entry if the service process may have restarted (in-memory map is volatile).
- Validate the cacheKey on the client side before binding the call.
- Handle IllegalStateException in the client and restart the buy flow from the beginning.
Example fix
// before
val token = billing.requestAuthProofToken(context, staleKey, password)
// after
val token = if (hasBuyFlowCache(staleKey)) billing.requestAuthProofToken(context, staleKey, password)
else runCatching { startBuyFlow(); requestAuthProofToken(context, newKey, password) }
.getOrThrow() Defensive patterns
Strategy: validation
Validate before calling
if (!hasBuyFlowCacheEntry(cacheKey)) {
throw IllegalStateException("Start buy flow first")
}
val token = requestAuthProofToken(context, cacheKey, password) Try / catch
try {
val token = requestAuthProofToken(context, cacheKey, password)
} catch (e: IllegalStateException) {
restartBuyFlow() // cache lost or stale
} Prevention
- Always run the buy-intent flow before requesting auth proof tokens
- Reuse the exact cacheKey returned by the earlier step
- Remember the cache is in-memory: re-acquire after process death
- Never persist cacheKeys across sessions
When it happens
Trigger: Calling requestAuthProofToken(context, cacheKey, password) with a key never populated by a prior acquire/buy-flow step, or after the cache entry was cleared/evicted, or from a different service instance than the one that populated the map.
Common situations: Client passes a stale cacheKey from an earlier session; buy-flow creation failed earlier but the client proceeded; service process was killed, losing the in-memory cache; key typo/protocol mismatch between caller and service.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Position already set using positionFromBounds()
- Position already set using position()
- App already listening
- Failed to obtain login token.
- Failed to retrieve device information.
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/807ab8644344b171.
Report an issue: GitHub.