Error Handling
Directory returns errors as RFC 7807 Problem Details with a stable code field alongside the standard fields. Responses use Content-Type: application/problem+json.
Error Response Structure
{ "type": "https://drs.xyz/errors/address-not-found", "title": "Address not found", "status": 404, "code": "ADDRESS_NOT_FOUND", "detail": "No active address found for \"nobody\"", "field": "address"}| Field | Type | Description |
|---|---|---|
type | string | Stable URI identifying the error kind |
title | string | Short, human-readable title |
status | integer | HTTP status code |
code | string | Machine-readable error code |
detail | string | Optional longer explanation |
field | string | Optional offending field path |
Implementations MAY add additional fields. Clients MUST ignore unknown fields.
Error Codes
| Code | Status | Meaning |
|---|---|---|
INVALID_REQUEST | 400 | Missing or malformed field, bad JSON, failed normalization |
ADDRESS_NOT_FOUND | 404 | No active address exists for the local part |
PAYLOAD_TOO_LARGE | 413 | Request body exceeds the 4 KiB limit |
UNSUPPORTED_MEDIA_TYPE | 415 | Content-Type must be application/json |
INTERNAL_ERROR | 500 | Unexpected server error |
KV_UNAVAILABLE | 503 | Storage backend unreachable |
Client-side verification failures are not HTTP responses — they are returned by the client library:
| Client error | When |
|---|---|
INVALID_SIGNATURE | Ed25519 verification failed against every published key |
EXPIRED_CONTRACT | expires_at is in the past beyond clock-skew tolerance |
NOT_YET_VALID | issued_at is in the future beyond clock-skew tolerance |
Design Rationale
DNS returns NXDOMAIN or an answer. HTTP returns a status code. Directory follows the same pattern. The protocol is a query and a response — it either resolves or it doesn’t. Complex error taxonomies belong in the operator’s implementation, not in the protocol.
Client Behavior
- 400 — fix the request. Check the
fieldvalue. - 404 — the address doesn’t exist. Don’t retry.
- 413 / 415 — client bug. Don’t retry.
- 500 — server error. May retry with backoff.
- 503 — temporary unavailability. Retry after a delay.
- Verification failure — refetch
_drskeyrecords once and retry before failing.