microg/GmsCore · error · StandardIntegrityException

Null callerKeyMd5

Error message

Null callerKeyMd5

What it means

warmUpIntegrityToken computes an MD5 fingerprint of the caller's encoded client key and throws StandardIntegrityException('Null callerKeyMd5') when the MD5 computation returns null. This means the caller client key could not be hashed, so the request cannot be authenticated.

Source

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

                val errorCode = intermediateIntegrityResponse.errorInfo?.let { error ->
                    if (error.errorCode == null) {
                        null
                    } else if (error.testErrorType == TestErrorType.REQUEST_EXPRESS) {
                        error.errorCode
                    } else if (error.testErrorType == TestErrorType.WARMUP) {
                        throw StandardIntegrityException(error.errorCode, "Server-specified exception")
                    } else null
                }

                val defaultAccountName: String = runCatching {
                    if (expressIntegritySession.webViewRequestMode != 0) {
                        RESULT_UN_AUTH
                    } else {
                        AccountManager.get(context).getAccountsByType(DEFAULT_ACCOUNT_TYPE).firstOrNull()?.name ?: RESULT_UN_AUTH
                    }
                }.getOrDefault(RESULT_UN_AUTH)

                val callerKeyMd5 = clientKey.encode().md5() ?: throw StandardIntegrityException("Null callerKeyMd5")
                val refreshClientKey = clientKey.newBuilder()
                    .generated(makeTimestamp(System.currentTimeMillis()))
                    .build()
                val fixedAdvice = IntegrityAdvice.Builder()
                    .advices(intermediateIntegrityResponse.integrityAdvice?.advices.ensureContainsLockBootloader())
                    .build()
                val intermediateIntegrityResponseData = IntermediateIntegrityResponseData(
                    intermediateIntegrity = IntermediateIntegrity(
                        expressIntegritySession.packageName,
                        expressIntegritySession.cloudProjectNumber,
                        defaultAccountName,
                        refreshClientKey,
                        intermediateIntegrityResponse.intermediateToken,
                        intermediateIntegrityResponse.serverGenerated,
                        expressIntegritySession.webViewRequestMode,
                        errorCode,
                        fixedAdvice
                    ),

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Verify the calling app passes a valid, non-empty client key to the integrity API
  2. Re-check how clientKey is built (generated timestamp, encoding) before the call
  3. Update Google Play services / the Play Integrity library version
  4. Clear Play Store / Play services data on the device to reset stored key state

Example fix

// before
val callerKeyMd5 = clientKey.encode().md5() ?: throw StandardIntegrityException("Null callerKeyMd5")
// after
val encoded = clientKey.encode()
require(!encoded.isEmpty()) { "Client key encoding produced no bytes" }
val callerKeyMd5 = encoded.md5() ?: throw StandardIntegrityException("Null callerKeyMd5")
Defensive patterns

Strategy: try-catch

Try / catch

try {
    warmUpIntegrityToken()
} catch (e: StandardIntegrityException) {
    if (e.message?.contains("callerKeyMd5") == true) {
        // re-bind integrity session / reset key material
    }
}

Prevention

When it happens

Trigger: clientKey.encode().md5() returns null during warmUpIntegrityToken — i.e., the encoded client key bytes are invalid or the hash helper fails.

Common situations: Malformed or empty client key passed by the calling app through the Play Integrity API binding; corrupted key material in the IPC bundle.

Related errors


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