Error codes
The errors each SDK raises, the licence states and reasons, and the cloud's renewal errors.
Errors are rare in normal use: a bad licence key does not raise, it puts the engine in evaluation mode. What does raise is listed here.
Engine errors
Every SDK raises the same three engine errors, in its own style:
| Error | When | What to do |
|---|---|---|
| Model | A model file is missing, unreadable or not a model pack | Check how the models are delivered: the bundled variant, the model directory, or the web model pack on your origin |
| Input | A frame, image, flow or config the engine cannot use (wrong size for its format, unknown flow) | A bug in the calling code: check the frame description and the flow |
| Feature not licensed | A valid licence does not include a feature the call needs. feature is card_ocr, face_match, liveness or fingerprints. Never raised in evaluation mode. |
Add the feature to the licence, or leave the step out of the flow |
| SDK | Types |
|---|---|
| Flutter | DigidException; FeatureNotLicensedException (a DigidException) with .feature |
| Web | DigidError with message, code and fatal; FeatureNotLicensedError (a DigidError) with code: "feature_not_licensed" and feature |
| Android | DigidException.Model, .Input, .Json, .FeatureNotLicensed(feature) (in tz.co.digid.sdk.ffi); the alias FeatureNotLicensedException |
| iOS | DigidError.Model, .Input, .Json, .FeatureNotLicensed(feature:); NidaFrameError.unsupportedPixelFormat and .lockFailed from the camera adapter |
Json (Android and iOS) means a result could not be read into the typed models, which points to an SDK version mismatch.
Web only: when fatal is true the engine instance has stopped and rejects every later call. Create a new engine to continue.
try {
await engine.newSession({ kind: "card_then_selfie", require_back: false });
} catch (e) {
if (e instanceof FeatureNotLicensedError) showUpgrade(e.feature);
else throw e;
}
Licence states and reasons
Applying a key returns a status, never an error:
state |
Meaning |
|---|---|
licensed |
The key is valid for this app |
grace |
Past its end date, inside the grace period. It still works; renew it. |
evaluation |
No valid key. Results are watermarked and never better than review. |
In evaluation mode, reason says why. The common reasons:
| Reason | What to do |
|---|---|
| no licence applied | Pass your key to the SDK at start-up |
| licence token is malformed | The key was cut or changed in transit: copy it again, as one line |
| unknown key id, or the key failed verification | The key was not issued by digid for this SDK, or the SDK is too old for it: download a fresh key and update the SDK |
| licence is not valid yet | Check the device clock |
| licence expired | Past the grace period: download a fresh key or renew |
| this app is not covered by the licence | Add the app to the licence in the customer portal: package name and signing certificate (Android), bundle id (iOS), origin (web) |
| local development origins need a sandbox licence | Use the sandbox key on localhost and *.test |
Renewal and usage errors
Renewal calls (renewLicence) raise an error with the cloud's code: RenewalRefusedException (Flutter, Android), RenewalRefused (iOS) or DigidError (Web), each with code and the missing days where there are any.
| Code | HTTP | Meaning |
|---|---|---|
usage_report_missing |
409 | No report, no renewal: some business days were never reported. details.missing_days lists them (ISO dates). |
insufficient_credit |
402 | The pay-as-you-go product has no credit left. Top it up in the customer portal. |
bootstrap_limit |
409 | A starting key was already issued for this licence in the last 30 days |
licence_expired, licence_not_active |
422 | The licence has ended or is not active. A key cannot be renewed past its licence. |
invalid_report |
422 | A report in the request belongs to another licence, app or phone |
missing_field |
422 | The body lacks report (usage) or request (renewal) |
renewal_failed |
Raised by the SDK when the response held no key it could read |
Other cloud API errors follow the same shape, {"error": {"code": …, "message": …, "details": …}}. See Cloud API.
Flow callbacks
The ready-made screens show their own message for camera and licence problems and keep running where they can. onError receives the same errors for your logs: camera failures, a refused camera permission, a licence that lacks a feature, and a document that could not be built.