Skip to content
v0.5.1GitHub

Reference

Status codes

applies to v0.5.1

Every 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.

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 Found
content-type: text/plain; charset=utf-8
404 Not Found: key 'nope' not found
HTTP/1.1 409 Conflict
content-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.
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.
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.
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.

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 Unavailable
retry-after: 1
503 Service Unavailable: the server is overloaded, retry later
HTTP/1.1 507 Insufficient Storage
retry-after: 5
507 Insufficient Storage: write blocked: disk space below threshold, retry in 5 s

A 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.