microg/GmsCore · error · StandardIntegrityException
IntegrityErrorCode.NONCE_TOO_LONG
IntegrityErrorCode.NONCE_TOO_LONG
Error message
Nonce too long.
What it means
The nonce byte array supplied to requestIntegrityToken is 500 bytes or larger, exceeding the service's maximum. The nonce is embedded in the signed response, so oversized values are rejected with IntegrityErrorCode.NONCE_TOO_LONG.
Source
Thrown at vending-app/src/main/kotlin/com/google/android/finsky/integrityservice/IntegrityService.kt:125
throw StandardIntegrityException(IntegrityErrorCode.INTERNAL_ERROR, "Null packageName.")
}
integrityData = callerAppToIntegrityData(context, packageName)
if (integrityData?.allowed != true) {
throw StandardIntegrityException(IntegrityErrorCode.INTERNAL_ERROR, "Not allowed to request integrity token.")
}
val playIntegrityEnabled = VendingPreferences.isDeviceAttestationEnabled(context)
if (!playIntegrityEnabled) {
throw StandardIntegrityException(IntegrityErrorCode.INTERNAL_ERROR, "API is disabled.")
}
val nonceArr = request.getByteArray(KEY_NONCE)
if (nonceArr == null) {
throw StandardIntegrityException(IntegrityErrorCode.INTERNAL_ERROR, "Nonce missing.")
}
if (nonceArr.size < 16) {
throw StandardIntegrityException(IntegrityErrorCode.NONCE_TOO_SHORT, "Nonce too short.")
}
if (nonceArr.size >= 500) {
throw StandardIntegrityException(IntegrityErrorCode.NONCE_TOO_LONG, "Nonce too long.")
}
val cloudProjectNumber = request.getLong(KEY_CLOUD_PROJECT, 0L)
val playCoreVersion = request.getPlayCoreVersion()
Log.d(TAG, "requestIntegrityToken(packageName: $packageName, nonce: ${nonceArr.encodeBase64(false)}, cloudProjectNumber: $cloudProjectNumber, playCoreVersion: $playCoreVersion)")
val packageInfo = context.packageManager.getPackageInfoCompat(packageName, SIGNING_FLAGS)
val timestamp = makeTimestamp(System.currentTimeMillis())
val versionCode = packageInfo.versionCode
val integrityParams = IntegrityParams(
packageName = PackageNameWrapper(packageName),
versionCode = VersionCodeWrapper(versionCode),
nonce = nonceArr.encodeBase64(noPadding = false, noWrap = true, urlSafe = true),
certificateSha256Digests = packageInfo.signaturesCompat.map {
it.toByteArray().sha256().encodeBase64(noPadding = true, noWrap = true, urlSafe = true)
},
timestampAtRequest = timestamp,
cloudProjectNumber = cloudProjectNumber.takeIf { it > 0L }View on GitHub (pinned to 157c9d86ac)
Solutions
- Hash the large payload and use the digest as the nonce: MessageDigest.getInstance("SHA-256").digest(payload) (32 bytes), storing the full payload server-side for comparison.
- Check nonceArr.size < 500 at the call site before sending the request.
- Remove unnecessary fields from the nonce payload; keep it to a compact, hashed summary.
- Avoid redundant encodings (e.g. Base64-encoding an already-encoded string) that inflate byte size.
Example fix
// before
val nonce = buildJsonString(requestDetails).toByteArray() // can exceed 500 bytes
// after
val nonce = MessageDigest.getInstance("SHA-256")
.digest(buildJsonString(requestDetails).toByteArray()) // 32 bytes
serverNonceStore.store(expectedHash = nonce) Defensive patterns
Strategy: validation
Validate before calling
fun isNonceTooLong(nonce: ByteArray) = nonce.size >= 500
if (isNonceTooLong(nonce)) nonce = MessageDigest.getInstance("SHA-256").digest(nonce) Type guard
fun ByteArray?.isNonceValid(): Boolean = this != null && size in 16..499
Try / catch
try {
integrityManager.requestIntegrityToken(request)
} catch (e: StandardIntegrityException) {
if (e.errorCode == IntegrityErrorCode.NONCE_TOO_LONG) {
hashPayloadAndRetry()
} else throw e
} Prevention
- Always hash large payloads (SHA-256) before using them as nonces
- Keep nonce payloads compact; store large data server-side
- Add a length assertion (size < 500) in the nonce helper
When it happens
Trigger: Calling requestIntegrityToken with a KEY_NONCE byte array whose size >= 500, e.g. serializing an entire request/response body, large JSON blob, or concatenated data into the nonce.
Common situations: Putting a full JSON document of request details into the nonce instead of a hash; appending debug/trace data; double-encoding (Base64 of Base64) inflating size; passing a whole file's bytes.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- IntegrityErrorCode.NONCE_TOO_SHORT
- Missing package name
- Server-specified exception
- Null callerKeyMd5
- IntegrityErrorCode.INTERNAL_ERROR
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/f2b9e108fd465688.
Report an issue: GitHub.