Error handling

Common errors, what they mean and recommended next steps.

The Keyless SDK uses three classes of errors, each error has an error code and an error message. Errors follow 3 main categories:

  • User errors: triggered by unintended or suspicious user behavior.

    • 30_000 and above.

  • Integration errors: triggered by a KeylessSDK integration misconfiguration.

    • These span from 20_000 to 30_000.

  • Internal errors: triggered by Keyless internals.

    • All errors below 20_000

If you're implementing the Keyless SDK, you should handle errors coming from the SDK since the error message is not intended for end users.

User errors

User errors have code that are 30_000 and above.

Error
Code
Description

Spoofing

30000

The user might be placing a picture or a video in front of the camera.

Timeout

30001

The face could not be recognized before the specified timed out. Note: This error is no longer returned from SDK version 5.0.1 and above given the Liveness timeout feature was deprecated. See Changelog for details.

Mask detected

30002

The user might be wearing a mask, or there might be something hiding their face. Note: mask detected will be part of live feedback and no longer returned as an error from SDK version 4.8.0 and above.

User cancelled

30003

The user manually cancelled the face recognition and processing.

Face not matching

30004

The face of user in front of the camera does not match the face currently enrolled with Keyless.

No network connection

30005

The device appears to be offline.

Device tampered

30006

The device seems tampered and could have been rooted or jailbroken.

User lockout

30007

The user is temporarily locked out of Keyless after too many failed authentication attempts. Note in case of a new device activation a a different lockout code 523 is returned.

Rejected

30008

Keyless did not manage to recognize the user but does not suspect any spoofing attempt.

Camera denied

30009

The user denied camera permission.

Liveness Environment Aware

20021

The device does not meet the requirements for environment-aware liveness detection.

Integration errors

Integration errors have codes that span from 20_000 to 30_000.

Integration errors can be solved by making sure you are not misusing the API surface of the SDK. You can solve it by reading the error message and addressing the issue. If errors persist, please keep the error code, error message and stacktrace and contact us.

Internal errors

All errors below 20_000 are classed as internal errors in that they relate to the response from our Core platform. Typically internal errors require investigation from Keyless support, however we've highlighted some of the more common ones here where action may be taken by the integrator.

Error
Code
Description
Notes / Recommendation

PROTOCOL_INVALID_MESSAGE

507

client-server mismatch suggesting an issue in communicating with the Core backend.

This could be due the network dropping, or an outdated (unsupported) core client trying to contact the latest core backend.

PROTOCOL_FAILED_TO_AUTHENTICATE_USER

512

The given user selfie was did not meet the threshold of an approved match - in simple terms we were not confident enough that this was the same face as the one registered to this Keyless ID

In most cases we advise our customers to advise positive intent and request that the user retries reminding them to make sure they are in a well lit environment, their face is centred and they do not anything covering their face.

Of course integrators should consider that this error code is triggered because the person attempting to authenticate is not the same person that is registered and handle accordingly.

PROTOCOL_MAX_NUMBER_OF_DEVICES_REACHED

539

The maximum number of devices in this has been reached. Note a maximum of 50 devices per Keyless ID is allowed. Note also that these do not all necessarily represent physical devices of a user (they could be backup or temporary client states that can be use to bind future devices for example).

Revoke some of the existing states/devices in order to generate new ones.

For SaaS customers this can be done either manually via the Keyless dashboard or programmatically via the Server API.

NET_CONNECTION_FAILED

1004

Network unavailable or server response unexpected.

If networking is available refer to 507.

CLIENT_INVALID_INPUT

1134

Incorrect or invalid parameter passed to a core function.

This may be solved by re-running the Keyless enrollment or authentication request. Alternatively the SDK and core client sync may be in a corrupted state.

If errors in this range persist and are unclear, please keep the error code, error message and stacktrace and contact us. If possible we'd also recommend enabling Keyless logging at TRACE level and sending these logs to us to further speed up the Keyless investigation.

Examples

val configuration = Keyless.AuthenticationConfiguration()

Keyless.authenticate(
    authenticationConfiguration = configuration,
    onCompletion = { result ->
        when (result) {
            is Keyless.KeylessResult.Success -> {
                Log.d("IntegratorActivity ", "Authenticate success")
            }
            is Keyless.KeylessResult.Failure -> {
                when (result.error) {
                    is KeylessUserError.FaceNotMatching -> Log.d("IntegratorActivity ", "Face not matching")
                    is KeylessUserError.MaskDetected -> Log.d("IntegratorActivity ", "Mask detected")
                    is KeylessUserError.Spoofing -> Log.d("IntegratorActivity ", "Spoofing detected")
                    is KeylessUserError.Timeout -> Log.d("IntegratorActivity ", "The operation timed out")
                    is KeylessUserError.UserCancelled -> Log.d("IntegratorActivity ", "The user cancelled the operation")
                    is KeylessUserError.NoNetworkConnection -> Log.d("IntegratorActivity ", "No network connection available")
                    is KeylessUserError.Lockout -> Log.d("IntegratorActivity ", "Your account is temporarily locked")
                    else -> {
                        Log.d("IntegratorActivity ", "Authenticate failure")

                        val errorCode = result.error.code
                        val errorMessage = result.error.message
                        val errorCause = result.error.cause?.printStackTrace()
                        // here you could display a generic error popup with the error code
                    }
                }
            }
        }
    }
)

Last updated

Was this helpful?