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
- 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).
- Update microG to a version where the relevant TransportHandler implements start().
- Before invoking, gate the request on connection capability flags (hasCtap1Support / hasCtap2Support / shouldBeUsedInstantly).
- 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
- Let capability checks choose the transport instead of hardcoding one
- Gate requests on shouldBeUsedInstantly()/connection support flags
- Keep microG updated so all built-in handlers override start()
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
- Transport ${transport} not supported
- Attachment ${attachment} not supported
- Attestation conveyance preference ${attachment} not supporte
- No response set.
- PublicKeyCredentialType ${type} not supported
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/6369f1882f64768b.
Report an issue: GitHub.