{"record":{"id":"17b56bd79e99f753","repo":"microg/GmsCore","slug":"unknown-err","errorCode":"UNKNOWN_ERR","errorMessage":"EID decrypt failed","messagePattern":"EID decrypt failed","errorType":"error_code","errorClass":"RequestHandlingException","httpStatus":null,"severity":"error","filePath":"play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/hybrid/transport/ClientTunnelTransport.kt","lineNumber":41,"sourceCode":"    private var decryptEid: ByteArray? = null\n\n    fun startConnecting() {\n        Log.d(TAG, \"startConnecting: \")\n        decryptEid = decryptEid()\n        val routingId = decryptEid!!.sliceArray(11..13)\n        val domainId = ((decryptEid!![15].toInt() and 0xFF) shl 8) or (decryptEid!![14].toInt() and 0xFF)\n        val tunnelId = CryptoHelper.endif(ikm = randomSeed, salt = ByteArray(0), info = byteArrayOf(2, 0, 0, 0), length = 16)\n\n        val webSocketConnectUrl = buildWebSocketConnectUrl(domainId, routingId, tunnelId)\n        Log.d(TAG, \"startConnecting: webSocketConnectUrl=$webSocketConnectUrl\")\n        if (websocket == null) {\n            websocket = TunnelWebsocket(webSocketConnectUrl, this)\n        }\n        websocket?.connect()\n    }\n\n    private fun decryptEid(): ByteArray {\n        val decryptEid = CryptoHelper.decryptEid(eid, randomSeed) ?: throw RequestHandlingException(ErrorCode.UNKNOWN_ERR, \"EID decrypt failed\")\n        if (decryptEid.size != 16 || decryptEid[0] != 0.toByte()) {\n            throw RequestHandlingException(ErrorCode.UNKNOWN_ERR, \"EID structure invalid\")\n        }\n        return decryptEid\n    }\n\n    fun stopConnecting() {\n        Log.d(TAG, \"stopConnecting: \")\n        websocket?.close()\n    }\n\n    override fun disconnected() {\n        Log.d(TAG, \"disconnected: \")\n        callback.onSocketClose()\n    }\n\n    override fun error(error: TunnelException) {\n        Log.d(TAG, \"error: \", error)","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/hybrid/transport/ClientTunnelTransport.kt#L23-L59","documentation":"The hybrid tunnel client holds the peer authenticator's EID (encrypted advertising identifier) plus a random seed. decryptEid() calls CryptoHelper.decryptEid(eid, randomSeed) and throws when it returns null, i.e. the EID could not be decrypted. Without the decrypted EID the client cannot build the BLE scan filter or derive the tunnel connection, so it fails with UNKNOWN_ERR.","triggerScenarios":"decryptEid() (called from startConnecting and connected) is invoked with an eid/randomSeed pair that CryptoHelper.decryptEid cannot decrypt — malformed/empty eid bytes, wrong seed, or ciphertext from a peer with an incompatible key.","commonSituations":"Receiving a garbled or truncated EID from the QR code / browser handoff payload; version mismatch between the crypto used by the peer (e.g. Google Chrome or iOS device) and this library's CryptoHelper; copy-paste error when passing the seed.","solutions":["Validate the eid and randomSeed payloads (length, encoding, base64 decodability) before starting the connection.","Confirm both sides use the same hybrid/EID crypto version (update microG or the peer browser).","Regenerate the handoff data — re-scan the QR code / restart the browser flow to get a fresh EID.","Log eid.size and seed presence at the call site to distinguish null-input from bad-ciphertext cases."],"exampleFix":"// before\nval decryptEid = CryptoHelper.decryptEid(eid, randomSeed)\n    ?: throw RequestHandlingException(ErrorCode.UNKNOWN_ERR, \"EID decrypt failed\")\n// after\nif (eid == null || randomSeed == null || eid.isEmpty || randomSeed.isEmpty) {\n    throw RequestHandlingException(ErrorCode.UNKNOWN_ERR, \"EID decrypt failed: missing eid or seed\")\n}\nval decryptEid = CryptoHelper.decryptEid(eid, randomSeed)\n    ?: throw RequestHandlingException(ErrorCode.UNKNOWN_ERR, \"EID decrypt failed: ciphertext/key mismatch\")","handlingStrategy":"validation","validationCode":"require(!eid.isNullOrEmpty() && !randomSeed.isNullOrEmpty()) { \"missing EID/seed for hybrid connection\" }","typeGuard":"fun isValidHandoff(eid: ByteArray?, seed: ByteArray?) = eid != null && seed != null && eid.isNotEmpty && seed.isNotEmpty","tryCatchPattern":"try { transport.startConnecting() } catch (e: RequestHandlingException) { if (e.message == \"EID decrypt failed\") restartHandoffFlow() }","preventionTips":["Base64-decode handoff payloads defensively and log sizes before use","Keep microG and the peer browser on compatible hybrid protocol versions","Treat a failed decrypt as 'regenerate the QR/handoff' rather than retrying the same bytes"],"tags":["fido","cable","crypto","eid","handoff"],"backgroundTag":"checksum-mismatch","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}