Reference
Status codes
applies to v0.5.1Every status code LuraDB uses, with its meaning and its typical cause. Four of them carry a special meaning for clients: 412 when a precondition fails, 428 when a precondition is required, 503 when a queue is full and 507 when a volume has too little free space.
LuraDB answers with 25 different status codes. The OpenAPI contract names 18 of them on its endpoints: 200, 201, 202, 204, 206, 400, 401, 403, 404, 409, 410, 412, 413, 428, 429, 500, 503 and 507. The other seven, 304, 405, 414, 415, 416, 422 and 431, come from the HTTP layer around the API; the tables below mark them. The generated pages of the REST API give the codes and conditions of each endpoint; this page is the one place to look a code up.
What an error looks like
Section titled “What an error looks like”An error answers with a plain-text body and the status in the response line. Most messages start with the status and its reason, followed by what is wrong; some, from the JSON and relational engines, are the bare description:
HTTP/1.1 404 Not Foundcontent-type: text/plain; charset=utf-8
404 Not Found: key 'nope' not foundHTTP/1.1 409 Conflictcontent-type: text/plain; charset=utf-8
duplicate primary key in table 't1'Read the status, not the text, in code; the text is for people and can change between releases. A few answers carry a header that tells the client what to do next:
| Header | On | Value |
|---|---|---|
Retry-After |
429, and 503 for a full queue |
1 second. |
Retry-After |
507 |
5 seconds. |
ETag |
412 |
The tag of the current version, unless the key or document does not exist. |
Cache-Control: no-store |
428 |
Keeps a cache from storing the answer. |
Allow |
405 |
The methods the path accepts. |
Content-Range |
206, 416 |
The range served, or bytes */<size> when it lies beyond the end. |
Success and not modified
Section titled “Success and not modified”| Code | Meaning | When |
|---|---|---|
200 |
OK | A read or write succeeded: a key stored, a document updated, a row read, a statement run, a permission set. |
201 |
Created | A domain, user, document, index, row or table was created, or an uploaded backup accepted. |
202 |
Accepted | The request started work in the background: a backup or restore job, the deletion of a domain, a re-index. Poll the job or the domain. |
204 |
No Content | A delete succeeded, or a read found a key in the explicit null state. |
206 |
Partial Content | A Range request on a backup download. |
304 |
Not Modified | A backup download with If-Modified-Since and no newer file. Not in the contract. |
Client errors
Section titled “Client errors”| Code | Meaning | Typical cause |
|---|---|---|
400 |
Bad Request | The request is malformed or breaks a rule of the API: an invalid domain, user or key name (400 Bad Request: Key length 257 exceeds maximum of 256 bytes), an If-Match that is not a tag, a JSON body that does not parse, a JSON search on a field without an index (field 'status' is not indexed in domain 'orders'), a SQL syntax error, a reserved field _key in a document, a lines of 0 for the logs, a URL path that is not valid UTF-8. |
401 |
Unauthorized | No Authorization: Bearer header, or a key that is unknown, removed or rotated. The body is Unauthorized. |
403 |
Forbidden | The key is valid but the account has no permission on the engine and domain, or the endpoint is for admins only. The body is Forbidden. |
404 |
Not Found | The key, document, row, table, domain, user, backup or restore does not exist, or the path is unknown. With the relational engine switched off, every /store-api/rel/… path answers an empty 404. |
405 |
Method Not Allowed | The path exists but not for this method, such as POST /health. The Allow header lists the methods. Not in the contract. |
409 |
Conflict | The request collides with what exists: a domain, user, table or index of that name exists (409 Conflict: Domain 'doomed' already exists, also while it is being deleted), a primary key or unique value is taken, a REFERENCES or key link has no target, a backup or restore job is already running, a re-index is running. |
410 |
Gone | The domain is being deleted: its data is purged in the background, and the name is unavailable until that ends. |
412 |
Precondition Failed | If-Match does not match the current version, If-Match names a key that does not exist, or If-None-Match: * finds the key. Nothing was written. A backup download answers 412 for a failed If-Unmodified-Since as well. |
413 |
Payload Too Large | The body is over the limit: 2 MiB for most endpoints (Failed to buffer the request body: length limit exceeded), json.bulk_body_limit_bytes for a bulk load, rel.import_body_limit_bytes for a table import. Also a bulk delete that selects more than domains.max_bulk_delete_keys keys, and a relational response over 32 MiB. |
414 |
URI Too Long | A URL of more than about 65 000 bytes. Not in the contract. |
415 |
Unsupported Media Type | An endpoint that reads JSON got no Content-Type: application/json: Expected request with `Content-Type: application/json` . Not in the contract. |
416 |
Range Not Satisfiable | A Range on a backup download that lies beyond the end of the file. Not in the contract. |
422 |
Unprocessable Entity | The body is valid JSON but does not have the shape the endpoint wants: Failed to deserialize the JSON body into the target type: missing field `name` . A body that is not JSON at all answers 400. Not in the contract. |
428 |
Precondition Required | The domain was created with require_conditional_writes and the write carries neither If-Match nor If-None-Match. |
429 |
Too Many Requests | The domain used up its budget of reads or writes per second (429 Too Many Requests: write rate limit exceeded). |
431 |
Request Header Fields Too Large | More header fields than the server accepts; a request with 200 fields was refused. Not in the contract. |
Server errors
Section titled “Server errors”| Code | Meaning | Typical cause |
|---|---|---|
500 |
Internal Server Error | An error the server did not expect, or a request it cannot serve: the log directory is unreadable for the log API, or a bulk delete by prefix meets a stored key longer than lsm.max_key_length (Key length 269 exceeds maximum of 256 bytes). Look in the log. |
503 |
Service Unavailable | A queue is full (503 Service Unavailable: the server is overloaded, retry later), the server is shutting down, a feature is switched off (JSON engine is disabled, backup is disabled, log access is disabled), or a data shard does not answer (/health, /store-api/metrics). |
507 |
Insufficient Storage | A volume is below its block threshold, or the memory of the server is at 95 % of its budget. The write was not applied; reads go on. |
The four that need client logic
Section titled “The four that need client logic”412 and 428 belong to conditional writes. On 412, read the key again, decide whether your change still applies, and retry with the new ETag that the answer carries. On 428, add If-Match: <tag> to change an existing key, or If-None-Match: * to create one.
503 and 507 mean the request was refused before it did anything, so it is safe to send again unchanged. Wait for the seconds in Retry-After first:
HTTP/1.1 503 Service Unavailableretry-after: 1
503 Service Unavailable: the server is overloaded, retry laterHTTP/1.1 507 Insufficient Storageretry-after: 5
507 Insufficient Storage: write blocked: disk space below threshold, retry in 5 sA 503 clears in seconds, once the queue drains. A 507 lasts until space is freed or memory drops, so do not retry in a tight loop: the server resumes writes only after every volume is above its resume threshold again. Troubleshooting tells what to do about both, and about 429, which also asks for a wait of one second.