microg/GmsCore · error · RuntimeException
oauthToken is null
Error message
oauthToken is null
What it means
The same requestGellerOauthToken function throws RuntimeException("oauthToken is null") when AccountManager.blockingGetAuthToken returns null for a valid account — the account exists but no auth token could be issued for the webhistory scope.
Source
Thrown at play-services-core/src/main/kotlin/com/google/android/gms/semanticlocationhistory/extensions.kt:50
const val E2EE_TYPE_URL = "type.googleapis.com/geller.oneplatform.GellerE2eeElement"
const val AES_GCM_IV_SIZE = 12
const val AES_GCM_TAG_BITS = 128
const val AES_KEY_SIZE = 32
const val SEMANTIC_TYPE_HOME = 1
const val SEMANTIC_TYPE_WORK = 2
const val SEARCH_WINDOW_DAYS = 30L
const val SECONDS_PER_DAY = 86400L
suspend fun Context.requestGellerOauthToken(accountName: String, scope: String = "oauth2:https://www.googleapis.com/auth/webhistory"): String {
val accountManager = AccountManager.get(this)
val account = accountManager.getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE).find {
it.name == accountName
}
if (account == null) throw RuntimeException("account is null")
return withContext(Dispatchers.IO) {
accountManager.blockingGetAuthToken(account, scope, true)
} ?: throw RuntimeException("oauthToken is null")
}
suspend fun Context.getObfuscatedGaiaId(accountName: String) = requestGellerOauthToken(accountName, AuthConstants.SCOPE_GET_ACCOUNT_ID)
private val weakCachedKeyMap = WeakHashMap<String, List<Pair<ByteArray, Int>>>()
fun loadKeyMaterials(context: Context, accountName: String): List<Pair<ByteArray, Int>> {
val result = weakCachedKeyMap.get(accountName)
if (!result.isNullOrEmpty()) {
return result
}
val keyManager = LocalKeyManager.getInstance(context)
val keys = keyManager.getKeysForDomain(accountName, ODLH_SECURITY_DOMAIN)
.ifEmpty { keyManager.getKeysForDomain(accountName, ODLH_SECURITY_DOMAIN_SHORT) }
val materials = keys.mapNotNull { key ->
val material = key.keyMaterial?.toByteArray() ?: return@mapNotNull null
if (material.size != AES_KEY_SIZE) return@mapNotNull null
material to (key.keyVersion ?: 0)View on GitHub (pinned to 157c9d86ac)
Solutions
- Invalidate the stale token (accountManager.invalidateAuthToken) and retry the request
- Check the account's auth state and prompt the user to sign in again
- Ensure microG's auth backend can reach Google servers (network/proxy checks)
- Catch RuntimeException and fall back to an unauthenticated / degraded feature path
Example fix
// before
val token = context.requestGellerOauthToken(accountName)
// after
val token = try {
context.requestGellerOauthToken(accountName)
} catch (e: RuntimeException) {
Log.w(TAG, "geller oauth token unavailable", e); null
} Defensive patterns
Strategy: retry
Validate before calling
val account = AccountManager.get(context).findAccount(accountName) ?: return null val hasAuth = true // ensure account is not flagged for re-auth in account settings
Type guard
suspend fun Context.safeGellerToken(accountName: String): String? =
try { requestGellerOauthToken(accountName) } catch (e: RuntimeException) { null } Try / catch
try {
val token = context.requestGellerOauthToken(accountName)
} catch (e: RuntimeException) {
accountManager.invalidateAuthToken(account.type, null)
retryWithReauth()
} Prevention
- Invalidate and refresh tokens when auth calls start returning null
- Prompt re-authentication after password changes
- Check network reachability of the auth backend before token requests
When it happens
Trigger: blockingGetAuthToken returns null: the account's auth session is expired, the user has not granted the auth scope, the account needs re-authentication (e.g. after password change), or AccountManager could not contact the auth backend (network/timeout is usually surfaced differently, but null can occur).
Common situations: Devices with stale Google credentials, accounts flagged for re-authentication, or the geller/webhistory scope being denied for the account on microG.
Related errors
- Missing required properties: scopes
- Missing required properties: account
- oauthToken is null
- account is null
- deleteAll was set to true but keys were also provided
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/92fa6c6b81d31bd9.
Report an issue: GitHub.