microg/GmsCore · error · RequestHandlingException

NOT_SUPPORTED_ERR

NOT_SUPPORTED_ERR

Error message

null

What it means

This is the base TransportHandler.start() implementation, which is intentionally unimplemented: every concrete transport handler (USB, NFC, BLE, internal) must override start(). Reaching it means a request was dispatched to a transport whose handler never overrode start(), so the library immediately fails the request with NOT_SUPPORTED_ERR and no message (message "null").

Source

Thrown at play-services-fido/core/src/main/kotlin/org/microg/gms/fido/core/transport/TransportHandler.kt:47

import javax.crypto.KeyAgreement
import javax.crypto.Mac
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

class AuthenticatorResponseWithUser<T: AuthenticatorResponse>(val response: T, val user: PublicKeyCredentialUserEntity?)

abstract class TransportHandler(val transport: Transport, val callback: TransportHandlerCallback?) {
    open val isSupported: Boolean
        get() = false

    open suspend fun start(
        options: RequestOptions,
        callerPackage: String,
        pinRequested: Boolean = false,
        pin: String? = null,
        credentialIdString: String? = null
    ): AuthenticatorResponseWithUser<*> =
        throw RequestHandlingException(ErrorCode.NOT_SUPPORTED_ERR)

    open fun shouldBeUsedInstantly(options: RequestOptions, credential: String? = null): Boolean = false
    fun invokeStatusChanged(status: String, extras: Bundle? = null) =
        callback?.onStatusChanged(transport, status, extras)

    private suspend fun ctap1DeviceHasCredential(
        connection: CtapConnection,
        challenge: ByteArray,
        application: ByteArray,
        descriptor: PublicKeyCredentialDescriptor
    ): Boolean {
        try {
            connection.runCommand(U2fAuthenticationCommand(0x07, challenge, application, descriptor.id))
            return true
        } catch (e: CtapHidMessageStatusException) {
            return e.status == 0x6985;
        } catch (e: CtapNfcMessageStatusException) {
            return e.status == 0x6985;

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Check which transport was chosen for the request and whether that transport actually supports the operation; retry over a supported transport (e.g. USB/ble).
  2. Update microG to a version where the relevant TransportHandler implements start().
  3. Before invoking, gate the request on connection capability flags (hasCtap1Support / hasCtap2Support / shouldBeUsedInstantly).
  4. If implementing a custom handler, override start() instead of inheriting the throwing base.

Example fix

// before (caller blindly uses handler)
val response = handler.start(options, callerPackage)
// after
if (!handler.shouldBeUsedInstantly(options, credentialId)) {
    throw RequestHandlingException(ErrorCode.NOT_SUPPORTED_ERR, "Transport ${handler.transport} does not support this operation")
}
val response = handler.start(options, callerPackage)
Defensive patterns

Strategy: type-guard

Validate before calling

check(handler.javaClass.method("start").declaringClass != TransportHandler::class.java) { "transport handler does not implement start()" }

Type guard

fun TransportHandler?.supportsStart(): Boolean = this != null && this::class != TransportHandler::class

Try / catch

try { handler.start(options, callerPackage) } catch (e: RequestHandlingException) { if (e.code == ErrorCode.NOT_SUPPORTED_ERR) failOverToNextTransport() }

Prevention

When it happens

Trigger: Authenticator flow dispatches start() to a base/abstract TransportHandler subclass that has not overridden it — i.e. the selected transport does not support the requested operation (register/sign) at all.

Common situations: Requesting an operation over a transport the device/handler doesn't support (e.g. new request type routed to a legacy handler); library version where a handler's start() override is missing; caller selecting a transport manually instead of letting capability checks pick one.

Related errors


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