microg/GmsCore · error · IllegalArgumentException

rolling start interval number missing

Error message

rolling start interval number missing

What it means

TemporaryExposureKeyProto.toKey() requires rolling_start_interval_number (the 10-minute interval at which the key becomes valid). If the received proto lacks this field, the elvis operator throws IllegalArgumentException 'rolling start interval number missing'. Without it the key's validity window cannot be computed, so the conversion fails.

Source

Thrown at play-services-nearby/core/src/main/kotlin/org/microg/gms/nearby/exposurenotification/ExposureNotificationServiceImpl.kt:249

            ExposureDatabase.with(context) { database ->
                database.noteAppAction(packageName, "getTemporaryExposureKeyHistory", JSONObject().apply {
                    put("result", status.statusCode)
                    put("response_keys_size", response.size)
                }.toString())
            }
            try {
                params.callback.onResult(status, response)
            } catch (e: Exception) {
                Log.w(TAG, "Callback failed", e)
            }
        }
    }

    private fun TemporaryExposureKeyProto.toKey(): TemporaryExposureKey = TemporaryExposureKey.TemporaryExposureKeyBuilder()
            .setKeyData(key_data?.toByteArray() ?: throw IllegalArgumentException("key data missing"))
            .setRollingStartIntervalNumber(rolling_start_interval_number
                    ?: throw IllegalArgumentException("rolling start interval number missing"))
            .setRollingPeriod(rolling_period ?: throw IllegalArgumentException("rolling period missing"))
            .setTransmissionRiskLevel(transmission_risk_level ?: 0)
            .build()

    private fun InputStream.copyToFile(outputFile: File) {
        outputFile.outputStream().use { output ->
            copyTo(output)
            output.flush()
        }
    }

    private fun MessageDigest.digest(file: File): ByteArray = file.inputStream().use { input ->
        val buf = ByteArray(4096)
        var bytes = input.read(buf)
        while (bytes != -1) {
            update(buf, 0, bytes)
            bytes = input.read(buf)
        }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Reject or repair export entries lacking rolling_start_interval_number before conversion
  2. Re-download the export and verify checksum/signature
  3. Default to a sane value only if your use case allows, otherwise skip the entry
  4. Ensure the diagnosis server publishes spec-compliant exports (all required TEK fields present)

Example fix

// before
.setRollingStartIntervalNumber(rolling_start_interval_number ?: throw IllegalArgumentException("rolling start interval number missing"))
// after
.setRollingStartIntervalNumber(rolling_start_interval_number ?: Int.MIN_VALUE.also { Log.w(TAG, "missing rolling start interval, skipping") }.let { return null })
Defensive patterns

Strategy: validation

Validate before calling

fun TemporaryExposureKeyProto.hasValidRollingStart(): Boolean =
    rolling_start_interval_number != null && rolling_start_interval_number > 0

Type guard

fun TemporaryExposureKeyProto?.isConvertibleToKey(): Boolean =
    this != null && key_data?.size() ?: 0 > 0 && rolling_start_interval_number != null && rolling_period != null

Try / catch

try {
    val key = proto.toKey()
} catch (e: IllegalArgumentException) {
    if (e.message?.contains("rolling start interval") == true) skipEntry(proto)
    else throw e
}

Prevention

When it happens

Trigger: Parsing an exposure-key export (TEK) proto whose rolling_start_interval_number field is unset; converting diagnosis keys fetched from a server that omitted the field.

Common situations: Malformed or spec-noncompliant diagnosis-server exports; partially written key files; test fixtures missing fields; custom key submission clients that build incomplete protos.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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