---
slug: "/docs/v1/integration-guide/real-world"
title: "Handle errors and offline use"
description: "Stage 10: handle errors and offline use with a clear outcome, verification steps and one next action."
section: "Integration Guide"
order: 25
audience: "all"
level: "intermediate"
last_updated: "2026-10-20"
version: "v1"
related: []
draft: false
layout: "guide"
---
## What you will do
Handle failures without trapping the [customer](/docs/v1/start/glossary#customer) or weakening access checks.
| What you see | What to do |
|---|---|
| INVALID_LICENSE | Check the full key, [public App ID](/docs/v1/start/glossary#public-app-id), [Sandbox](/docs/v1/start/glossary#sandbox) selection and matching customer email. |
| MAX_DEVICES_REACHED | Deactivate an old installation or inspect [Devices](/docs/v1/start/glossary#device). Do not make random identities. |
| SIGNATURE_INVALID / cached signature error | Keep access locked. Check the runtime, clock and SDK compatibility notes; do not disable verification. |
| NOT_ACTIVATED | Run activate in the same private state directory first. |
| NETWORK_ERROR / no connection | Reconnect. A first [activation](/docs/v1/start/glossary#activation) needs internet; no cached response means no offline grant. |
| LICENSE_EXPIRED / LICENSE_REVOKED / LICENSE_SUSPENDED | Explain the state to the customer and provide support; never silently convert it to valid. |
For normal launches, check can reuse a verified cache before its signed next_validation_at. After a network failure, any offline decision must still verify its signature, bindings, clock and offline_grace_until. Grace is based on signed server time, not “another N days after failure”.
1. Keep first activation online.
2. Use the same sample's check command to exercise the SDK's real cache policy.
3. Treat missing, corrupted, stale or clock-rollback cache as a denial requiring reconnection.
4. To move computers, run deactivate on the old installation while online, then activate on the new one.
:::tabs
:::tab python Python
Release this installation:
```bash
.venv/bin/python license-check.py deactivate
```
Expected output: Device released. This action does not grant access. Use activate on the replacement installation.
:::
:::tab javascript JavaScript / Node.js
Release this installation:
```bash
node license-check.mjs deactivate
```
Expected output: Device released. This action does not grant access. Use activate on the replacement installation.
:::
:::tab php PHP
Release this installation:
```bash
php license-check.php deactivate
```
Expected output: Device released. This action does not grant access. Use activate on the replacement installation.
:::
:::tab csharp C# / .NET
Release this installation:
```bash
dotnet run --project Guide.csproj -- deactivate
```
Expected output: Device released. This action does not grant access. Use activate on the replacement installation.
:::
:::tab curl cURL / other language
Use your REST project's deactivation operation with the stored [activation token](/docs/v1/start/glossary#activation-token). Keep the installation identity stable and do not treat a release response as an access grant.
Use the selected language SDK or REST client from [SDKs and languages](/docs/v1/sdks/overview), its [signature verifier](/docs/v1/security/verify-ed25519), and the supported [webhook verifier](/docs/v1/guides/verify-webhook-signatures).
:::
:::

Do not erase local files as a substitute for server deactivation; that can abandon a device seat. Reset devices in the dashboard only after an authenticated support decision.
## Expected result
Customers get a clear message: “We could not check your [license](/docs/v1/start/glossary#license). Reconnect or contact support.” They never see raw keys, tokens or stack traces.
## If it does not work
An offline denial can be a correct security outcome. The current C# Unicode cache issue needs explicit testing; permission-protected files are not an OS vault.
## Stage checklist
- I tested a disconnected launch and an expired cache.
- I tested a full device limit and a successful release.
- I keep unknown or unverified states locked.

## Next steps
[Continue to Stage 11: Protect tokens and identity](/docs/v1/integration-guide/storage)
