Errors
Standard conventions for ScaiDNS error responses. This page covers the shape, the status codes, and how to interpret the most common cases. See Error Codes for the exhaustive reference.
Error response shape#
All error responses use this shape:
1 2 3 | |
For some structured errors (validation failures, conflicts), detail is an object instead of a string:
1 2 3 4 5 6 7 | |
Pydantic validation errors from FastAPI follow the standard pattern:
1 2 3 4 5 6 7 8 9 | |
HTTP status codes#
ScaiDNS uses standard HTTP status codes.
2xx — Success#
| Code | Meaning |
|---|---|
200 OK |
GET, PATCH, POST with a response body |
201 Created |
POST creating a resource (sometimes — usually just 200 with body) |
204 No Content |
DELETE or write that returns no body |
4xx — Caller error#
| Code | Meaning | Typical cause |
|---|---|---|
400 Bad Request |
Malformed request or invalid input | Missing field, bad enum value, invalid record content |
401 Unauthorized |
Missing or invalid credentials | No X-API-Key/Authorization header; expired token; invalid signature |
403 Forbidden |
Authenticated but not allowed | Insufficient permissions, IP whitelist mismatch, cross-tenant attempt |
404 Not Found |
Resource doesn't exist (or you can't see it) | Wrong UUID, soft-deleted without ?include_deleted, tenant scoping |
409 Conflict |
Write conflicts with current state | Duplicate domain name, record collision (CNAME + A), role already assigned |
422 Unprocessable Entity |
Schema validation failed | Pydantic validation errors; usually a typed detail array |
429 Too Many Requests |
Rate limit exceeded | API key or global rate limit hit; check Retry-After header |
5xx — Server error#
| Code | Meaning | What to do |
|---|---|---|
500 Internal Server Error |
Unhandled exception | Retry with backoff; check platform health; if it persists, contact support |
502 Bad Gateway |
PowerDNS or ScaiKey unreachable | Usually transient; retry |
503 Service Unavailable |
Maintenance or overload | Retry with backoff |
504 Gateway Timeout |
PowerDNS or ScaiKey slow | Retry; check dashboards |
Common patterns#
Validation failures#
On POST and PATCH with invalid input, expect 422:
1 2 3 4 5 | |
Fix the input and retry.
Tenant mismatches#
Trying to read a resource from another tenant returns 404, not 403. This is intentional — leaking existence-by-status would let a caller enumerate resources across tenant boundaries.
Permission failures#
Trying to take an action your role doesn't permit returns 403:
1 | |
Check effective permissions: GET /api/v1/roles/users/{your_id}/permissions?domain_id={domain}.
Soft delete / not-found#
A soft-deleted domain returns 404 on normal reads. To restore:
1 2 | |
Record conflicts#
DNS has its own rules about which records can coexist:
CNAMEandA/AAAAcan't share a name.DNAMEand any other record can't share a name.NSat the zone apex requires at least one to remain present.
Violations return 409 with specifics:
1 2 3 4 5 6 7 | |
DNSSEC errors#
Particular cases to watch:
- Enabling when already enabled.
409— disable first or use rotate. - Confirming DS that doesn't match KSK.
400— check thekey_taganddigest. - Disabling with DS still published. Allowed, but resolvers will see broken DNSSEC. Remove DS at registrar first.
Rate limiting headers#
When you approach a rate limit, responses include:
1 2 3 | |
When exceeded (429):
1 | |
The Retry-After value is either seconds or an HTTP date.
Idempotency#
Most state changes are not idempotent at the HTTP level. Retrying a failed POST /records may create a duplicate if the first attempt partially succeeded. The server protects against this with:
- Unique constraints on
(domain_id, name, type, content)— duplicate records return409. - Bulk operations default to atomic (all-or-nothing) mode; partial success requires opting in with
continue_on_error.
If you need client-side idempotency, keep a record of the last successful create and check for its existence before retrying.
Audit trail#
Every write goes to the audit log. If an operation succeeds but the response was lost in transit, you can inspect GET /api/v1/admin/audit-logs to confirm the mutation happened before retrying.
What's next#
- Error Codes reference — exhaustive code list.
- API Guides — task-oriented walkthroughs showing error handling in context.