---
title: Error Codes
path: reference/error-codes
status: published
---

ScaiDrive does not currently emit a machine-readable `error.code` field. Error responses look like:

```json
{"detail": "<human-readable message>"}
```

The HTTP status code is the authoritative signal for branching. The `detail` string is for display and logs — don't parse it. For the conceptual guide including the validation-error shape, see [Errors](/docs/scaidrive/core-concepts/errors).

This page collects the HTTP-status-code-to-condition map alphabetically by category so you can find the right status for a given failure.

## Status codes by category

### Authentication and authorization

| Status | Condition |
|--------|-----------|
| 401 | Token missing, invalid signature, wrong issuer, expired |
| 403 | User suspended; insufficient scope; user lacks the required permission on the resource |
| 403 | Action only allowed for the resource owner (ownership transfer, share delete) |

### Input validation

| Status | Condition |
|--------|-----------|
| 400 | Path or query input is malformed |
| 422 | Request body fails Pydantic schema validation — `detail` is an array, one entry per failing field. See [Validation errors](/docs/scaidrive/core-concepts/errors#validation-errors-422) |

### Resources

| Status | Condition |
|--------|-----------|
| 404 | Resource doesn't exist, or isn't visible to the caller (we don't distinguish — hides existence from unauthorized callers) |
| 410 | Resource is soft-deleted (restore before reuse), or an invitation/link/upload session has expired |

### Conflicts

| Status | Condition |
|--------|-----------|
| 409 | Name collision (file or folder sibling) |
| 409 | Sync `base_version_id` doesn't match current server version |
| 409 | Invitation already accepted or declined |
| 409 | Share member or principal already exists |
| 409 | Connector sync already running |

### Storage limits

| Status | Condition |
|--------|-----------|
| 413 | Upload exceeds tenant's per-file size cap |
| 507 | Quota would be exceeded (share, user, group, tenant, or partner level). The `detail` message names the level |

### Sharing — external links (recipient-facing)

| Status | Condition |
|--------|-----------|
| 401 | Link requires a password and none was supplied, or the password is wrong |
| 403 | Caller IP not in allow-list; email not in allow-list for require_email links |
| 410 | Link expired, revoked, or disabled |
| 429 | Download or view cap reached |

### Connectors

| Status | Condition |
|--------|-----------|
| 401 | SMB or SharePoint credentials rejected by the external source |
| 409 | Connector already syncing |
| 502 | SMB/SharePoint source unreachable |

### Rate limiting

| Status | Condition |
|--------|-----------|
| 429 | Per-key, per-user, or per-tenant rate limit hit. Honor `Retry-After` header |

### Server / upstream

| Status | Condition |
|--------|-----------|
| 500 | Unexpected server failure |
| 502 | ScaiKey, Weaviate, S3, or connector source unreachable |
| 503 | Service draining or readiness probe failing |
| 504 | Upstream timed out |

## Validation error types

The `type` field on each validation-error entry comes from Pydantic. Common values you'll see:

| Type | Meaning |
|------|---------|
| `missing` | Required field absent |
| `enum` | Value not in the allowed enum |
| `string_type` / `int_type` / `bool_type` | Wrong primitive type |
| `string_too_short` / `string_too_long` | Length constraint |
| `less_than_equal` / `greater_than_equal` | Numeric range |
| `value_error` | Custom validator rejected the value |

For the full list, see [Pydantic's validation error reference](https://docs.pydantic.dev/latest/errors/validation_errors/).

## Related

- [Errors](/docs/scaidrive/core-concepts/errors) — error shape, retry strategy, streaming/WebSocket error handling.
- [Rate Limiting](/docs/scaidrive/advanced/rate-limiting)
- [Troubleshooting](/docs/scaidrive/operations/troubleshooting)