> For the complete documentation index, see [llms.txt](https://docs.veilio.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.veilio.xyz/documentation/great-to-know/troubleshooting.md).

# Troubleshooting

#### 401 `AUTH_ERROR`

**Causes**

* Missing API key
* Invalid or revoked API key
* Using a dashboard-only route with an API key (e.g. `DELETE /api/tokens/[id]` requires a session — use `POST /api/tokens/shred` from API instead)

**Fix**

* Verify `Authorization: Bearer <key>` or `X-API-Key: <key>`
* Use the correct key for the environment (dev vs prod)
* For programmatic shred: `POST /api/tokens/shred` or `POST /api/tokens/shred-bulk` (session)

***

#### 400 `VALIDATION_ERROR`

**Cause:** missing fields or invalid payload.

**Fix:** validate the body against HTTP Integration or the API Reference.

Common dataset upload messages:

| Message                                    | Fix                                                 |
| ------------------------------------------ | --------------------------------------------------- |
| `Missing file`                             | Send multipart field `file`                         |
| `columnPolicies JSON string required`      | Pass `columnPolicies` as a JSON string in form data |
| `Missing policy for column "..."`          | Add a policy entry for every column                 |
| `Policy references unknown column "..."`   | Remove extra policy keys                            |
| `JSON dataset must be an array of objects` | Fix JSON shape                                      |
| `Too many cells (max N)`                   | Reduce file size or split the import                |
| `File exceeds max size (N bytes)`          | Split file or contact support for limit increase    |

***

#### 403 `PLAN_LIMIT`

**Cause:** monthly plan quota exceeded (tokens created, API requests, API keys, or datasets).

**Fix**

* Check dashboard usage
* Upgrade plan on `/dashboard/billing`
* For historical import: use a **MIGRATION** API key and ensure migration budget is active (Migration Mode)

***

#### 403 `PLAN_LIMIT_REACHED` (organization invite)

**Cause:** member limit for plan (Starter = 1, Pro = 2).

**Fix:** upgrade to Pro or Enterprise, or contact Veilio for custom `maxMembers`.

***

#### 403 `FORBIDDEN` (VIEWER role)

**Cause:** VIEWER role cannot tokenize, shred, or upload datasets.

**Fix:** ask OWNER/DPO for MEMBER role or API key whitelist.

***

#### 408 `TIMEOUT_ERROR`

**Cause:** request exceeded server or client timeout (large bulk or format operations).

**Fix**

* Reduce batch size (`tokenize/bulk`, `detokenize/bulk`)
* Increase client timeout (SDK: `timeout` / `max_retries`)
* Retry with exponential backoff

***

#### 410 `TOKEN_SHREDDED`

**Cause:** the token was cryptographically shredded (manual shred, retention TTL expired, or GDPR erasure).

**Fix**

* Do **not** retry detokenization — the plaintext is permanently destroyed
* Handle gracefully in your app (show "data no longer available")
* Create a new token if the user provides fresh data

SDK handling:

```ts
// JavaScript
import { TokenShreddedError } from "@veilio/sdk";
```

```python
# Python
from veilio_sdk import TokenShreddedError
```

***

#### 413 `PAYLOAD_TOO_LARGE` (datasets)

**Cause:** dataset file exceeds `VEILIO_DATASET_MAX_BYTES` (default **320 MB**).

**Fix:** split the file into multiple uploads or contact support.

***

#### 429 `RATE_LIMIT_ERROR`

**Cause:** too many requests in a short window.

**Fix:** honor `Retry-After`, use exponential backoff, prefer bulk endpoints. The official SDKs retry automatically.

Response headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `Retry-After`.

***

#### 500 `INTERNAL_ERROR`

**Fix:** retry with backoff; contact <support@veilio.fr> with timestamp, endpoint, and `event_id` if available from SIEM.

***

#### Migration mode errors

| Message              | Fix                                                                       |
| -------------------- | ------------------------------------------------------------------------- |
| Migration not active | Activate from `/dashboard/onboarding` or `POST /api/onboarding/migration` |
| Budget exhausted     | Increase allowance or contact support                                     |
| Budget expired       | Re-activate migration window                                              |
| Freemium plan        | Migration requires Starter/Pro/Enterprise                                 |

***

#### Dataset access token errors

| Message                                       | Fix                                                                  |
| --------------------------------------------- | -------------------------------------------------------------------- |
| `Dataset not found`                           | Check dataset ID and organization scope                              |
| `Dataset share keys cannot be used to import` | Use a standard API key or dashboard for upload                       |
| Token expired                                 | Generate a new access token (`POST /api/datasets/[id]/access-token`) |

Max TTL for dataset access tokens: **7 days**. Default on upload: **48 hours**.

***

#### On-premise license errors

| Symptom                                         | Fix                                                                      |
| ----------------------------------------------- | ------------------------------------------------------------------------ |
| Instance won't start, license expired > 30 days | Renew license on control plane                                           |
| Read-only mode                                  | License in grace period — renew before 30-day window ends                |
| Auto-refresh fails                              | Check `VEILIO_LICENSE_REFRESH_TOKEN` and outbound HTTPS to control plane |

See Installation guide.

***

#### Stripe / billing (SaaS)

* **Double charge risk:** do not assign manual Enterprise in admin while a Stripe subscription is still active — cancel Stripe first.
* **Org quotas wrong:** ensure the org was created before Stripe checkout so `organizationId` is on the subscription row.

{% hint style="info" %}
If you have any issues or suggestions, reach out at <https://veilio.fr/contact> or <support@veilio.fr>.
{% endhint %}
