microg/GmsCore · error · StandardIntegrityException

IntegrityErrorCode.API_NOT_AVAILABLE

IntegrityErrorCode.API_NOT_AVAILABLE

Error message

Not allowed visit

What it means

requestExpressIntegrityToken throws StandardIntegrityException with IntegrityErrorCode.API_NOT_AVAILABLE and message 'Not allowed visit' when callerAppToIntegrityData reports the calling app is not allowed to use the express integrity API. The service gates access per-caller and rejects unauthorized packages.

Source

Thrown at vending-app/src/main/kotlin/com/google/android/finsky/expressintegrityservice/ExpressIntegrityService.kt:275

                val exception = it as? StandardIntegrityException ?: StandardIntegrityException(it.message)
                Log.w(TAG, "warm up has failed: code=${exception.code}, message=${exception.message}", exception)
                visitData?.updateAppIntegrityContent(context, System.currentTimeMillis(), "$TAG visited failed. ${exception.message}")
                callback?.onWarmResult(bundleOf(KEY_ERROR to exception.code))
            }
        }
    }

    override fun requestExpressIntegrityToken(bundle: Bundle, callback: IExpressIntegrityServiceCallback?) {
        Log.d(TAG, "requestExpressIntegrityToken bundle:$bundle")
        lifecycleScope.launchWhenCreated {
            runCatching {
                val callingPackageName = bundle.getString(KEY_PACKAGE_NAME)
                if (callingPackageName == null) {
                    throw StandardIntegrityException(IntegrityErrorCode.INTERNAL_ERROR, "Null packageName.")
                }
                visitData = callerAppToIntegrityData(context, callingPackageName)
                if (visitData?.allowed != true) {
                    throw StandardIntegrityException(IntegrityErrorCode.API_NOT_AVAILABLE, "Not allowed visit")
                }
                val playIntegrityEnabled = VendingPreferences.isDeviceAttestationEnabled(context)
                if (!playIntegrityEnabled) {
                    throw StandardIntegrityException(IntegrityErrorCode.API_NOT_AVAILABLE, "API is disabled")
                }

                val expressIntegritySession = ExpressIntegritySession(
                    packageName = callingPackageName,
                    cloudProjectNumber = bundle.getLong(KEY_CLOUD_PROJECT, 0L),
                    sessionId = Random.nextLong(),
                    requestHash = bundle.getString(KEY_NONCE),
                    originatingWarmUpSessionId = bundle.getLong(KEY_WARM_UP_SID, 0),
                    verdictOptOut = bundle.getIntegerArrayList(KEY_REQUEST_VERDICT_OPT_OUT),
                    webViewRequestMode = bundle.getInt(KEY_REQUEST_MODE, 0)
                )

                Log.d(TAG, "requestExpressIntegrityToken session:$expressIntegritySession}")

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Confirm the app's package name and signing key are registered/allowed for express integrity
  2. Install the app from an approved distribution channel (Play Store)
  3. Check server-side allowlist configuration for the package
  4. Fall back to the standard Integrity API if express access is not granted

Example fix

// before
integrityManager.requestExpressIntegrityToken(bundle, callback)
// after
if (isExpressIntegrityAllowed(context)) {
    integrityManager.requestExpressIntegrityToken(bundle, callback)
} else {
    // fall back to standard integrity token flow
}
Defensive patterns

Strategy: fallback

Validate before calling

// check caller eligibility hints: distribution channel + signature
val isFromPlay = context.packageManager.getInstallerPackageName(context.packageName) == "com.android.vending"

Try / catch

try {
    integrityManager.requestExpressIntegrityToken(bundle, callback)
} catch (e: StandardIntegrityException) {
    if (e.statusCode == IntegrityErrorCode.API_NOT_AVAILABLE) {
        // fall back to standard Integrity API
    }
}

Prevention

When it happens

Trigger: Calling requestExpressIntegrityToken from a package whose callerAppToIntegrityData result has allowed != true (not on the allowlist or flagged by policy).

Common situations: App not allowlisted for express integrity on this device/account; sideloaded or repackaged APK with a different signature; policy server denies the caller.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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