microg/GmsCore · error · StandardIntegrityException
IntegrityErrorCode.NETWORK_ERROR
IntegrityErrorCode.NETWORK_ERROR
Error message
DroidGuard failed.
What it means
DroidGuard (Google's on-device attestation/integrity check) returned a payload beginning with the error prefix instead of a usable token, so the service cannot continue and throws IntegrityErrorCode.NETWORK_ERROR with message "DroidGuard failed.". This indicates the device-side DroidGuard verdict step failed, typically due to connectivity, device integrity, or Play Services issues.
Source
Thrown at vending-app/src/main/kotlin/com/google/android/finsky/integrityservice/IntegrityService.kt:180
val authToken = getAuthToken(context, AUTH_TOKEN_SCOPE)
if (TextUtils.isEmpty(authToken)) {
Log.w(TAG, "requestIntegrityToken: Got null auth token for type: $AUTH_TOKEN_SCOPE")
}
Log.d(TAG, "requestIntegrityToken authToken: $authToken")
val droidGuardData = withContext(Dispatchers.IO) {
val droidGuardResultsRequest = DroidGuardResultsRequest()
droidGuardResultsRequest.bundle.putString("thirdPartyCallerAppPackageName", packageName)
Log.d(TAG, "Running DroidGuard (flow: $INTEGRITY_FLOW_NAME, data: $data)")
val droidGuardToken = DroidGuard.getClient(context).getResults(INTEGRITY_FLOW_NAME, data, droidGuardResultsRequest).await()
Log.d(TAG, "Running DroidGuard (flow: $INTEGRITY_FLOW_NAME, droidGuardToken: $droidGuardToken)")
Base64.decode(droidGuardToken, Base64.NO_PADDING or Base64.NO_WRAP or Base64.URL_SAFE).toByteString()
}
if (droidGuardData.utf8().startsWith(INTEGRITY_PREFIX_ERROR)) {
Log.w(TAG, "droidGuardData: ${droidGuardData.utf8()}")
throw StandardIntegrityException(IntegrityErrorCode.NETWORK_ERROR, "DroidGuard failed.")
}
val integrityRequest = IntegrityRequest(
params = integrityParams,
flowName = INTEGRITY_FLOW_NAME,
droidGuardTokenRaw = droidGuardData,
playCoreVersion = playCoreVersion,
playProtectDetails = PlayProtectDetails(PlayProtectState.PLAY_PROTECT_STATE_NO_PROBLEMS),
appAccessRiskDetailsResponse = AppAccessRiskDetailsResponse(
installedAppsSignalDataWrapper = InstalledAppsSignalDataWrapper("."),
screenCaptureSignalDataWrapper = ScreenCaptureSignalDataWrapper("."),
screenOverlaySignalDataWrapper = ScreenOverlaySignalDataWrapper("."),
accessibilityAbuseSignalDataWrapper = AccessibilityAbuseSignalDataWrapper(),
displayListenerMetadataWrapper = DisplayListenerMetadataWrapper(
lastDisplayAddedTimeDelta = makeTimestamp(SystemClock.elapsedRealtimeNanos())
)
)
)View on GitHub (pinned to 157c9d86ac)
Solutions
- Retry the request with exponential backoff — DroidGuard failures are often transient.
- Check network connectivity and that Google Play Services is up to date and enabled on the device.
- Catch IntegrityErrorCode.NETWORK_ERROR and surface a retryable state to the user rather than treating it as a policy violation.
- Test on a known-good device to rule out device-integrity (root/emulator) causes; escalate to Play Console support if persistent on healthy devices.
Example fix
// before
integrityManager.requestIntegrityToken(request)
// after
try {
integrityManager.requestIntegrityToken(request)
} catch (e: StandardIntegrityException) {
if (e.errorCode == IntegrityErrorCode.NETWORK_ERROR) {
scheduleRetryWithBackoff() // transient DroidGuard failure
} else throw e
} Defensive patterns
Strategy: retry
Validate before calling
// No pre-call validation possible; check connectivity first
val cm = context.getSystemService(ConnectivityManager::class.java)
val online = cm.activeNetwork?.let { cm.getNetworkCapabilities(it)?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) } == true Try / catch
try {
integrityManager.requestIntegrityToken(request)
} catch (e: StandardIntegrityException) {
if (e.errorCode == IntegrityErrorCode.NETWORK_ERROR) {
retryWithExponentialBackoff(maxAttempts = 3)
} else throw e
} Prevention
- Implement exponential-backoff retries for NETWORK_ERROR from integrity calls
- Verify Google Play Services is installed and updated on target devices
- Distinguish transient network errors from permanent device-integrity failures in telemetry
- Test on healthy physical devices to rule out root/emulator causes
When it happens
Trigger: requestIntegrityToken where the DroidGuard result for flow INTEGRITY_FLOW_NAME decodes to UTF-8 starting with INTEGRITY_PREFIX_ERROR — i.e. DroidGuard itself reports a failure rather than returning a token.
Common situations: Device offline or flaky network during the attestation; Play Services/device issues (rooted, unlocked bootloader, unlicensed device); Google Play Services out of date or disabled; transient server-side DroidGuard failures under load.
Related errors
- Signature invalid
- Network URL required
- familyResponse is null
- pageContent is null
- DroidGuard should not be available locally
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/1c2f968e0b5c89ae.
Report an issue: GitHub.