Overview#
This page lists the statuses a client can receive from TERSL/DB, grouped by what the client should do: retry unchanged, change the request, establish whether a write landed, or stop. Each row gives the first line of the body as the service writes it; X stands for a namespace name and N for a number.
Read the status doctrine first. A 200 from the Issue route means the request was processed. It does not mean every line in it succeeded: refusals inside a processed request are reported in the Messages channel and counted in Terse-Diagnostics.
200 and the other successes#
| Status | When | Body | Headers |
|---|---|---|---|
200 |
The request was processed. On /issue this includes an Expected-Csn mismatch, a write refused by the grants (TERSE-SEC-001), language diagnostics, and a resend under an idempotency key that already committed (info: duplicate of csn N; not re-applied). |
The framed answer, the document, or the stream. | Terse-Csn, Terse-Diagnostics, Server-Timing; Terse-Chain on a namespace with a verifiable record |
201 |
A playback session was opened. | The session document. | Location, Terse-Playback, Terse-As-Of-Csn |
202 |
A fork or a scrub was queued. | The fork or scrub document. | Location; Terse-Csn on a fork |
A refusal inside a 200 is not retried unchanged. An Expected-Csn mismatch means the namespace moved: read the head, decide whether the write still applies, and resend with the new CSN.
Retry unchanged#
These statuses mean the request was not processed because of load, a rate limit or a temporary condition. Nothing was applied. Wait for Retry-After seconds and send the same request again. Every 429 and 503 carries Retry-After.
| Status | When | First line of the body | Headers |
|---|---|---|---|
429 |
A rate window of the account's plan refused the request: the wait would be longer than the plan allows, or too many requests are already waiting. Write windows are checked after the body is read. | error: request rate limit exceeded for this tenant; nothing was processed, or the same sentence for the throughput limit, or error: …this tenant's 30-day request allowance is spent for now and refills continuously… (or the write or data-out allowance) |
Retry-After (the exact wait), RateLimit-Policy, RateLimit |
429 |
Too many requests are in flight for the namespace or the account. | error: too many requests in flight for namespace 'X'; nothing was processed, or …for this tenant… |
Retry-After |
503 |
The deployment is at its in-flight limit. | error: this deployment is at its in-flight limit; nothing was processed |
Retry-After |
503 |
The deployment cannot open the namespace within its memory limit. | error: this deployment is at its memory limit; nothing was processed |
Retry-After |
503 |
Another writer holds the namespace. | error: namespace 'X' is held by another writer; nothing was processed (on history: …; nothing was read) |
Retry-After; no Terse-Csn |
503 |
The write lost every attempt to commit under contention. | error: TERSE-STO-001: namespace 'X' is under write contention; nothing was committed |
Retry-After; Terse-Csn with the head that stands |
503 |
An exclusive load is running on the namespace. | error: TERSE-LOAD-002: namespace X is being loaded; nothing was processed |
Retry-After, estimated from the bytes the load has left |
503 |
A load cannot start: the service is running as many loads as it allows, or the account already has one running. | error: TERSE-LOAD-004: … or error: TERSE-LOAD-005: … |
Retry-After |
503 |
The fork or scrub queue is full. | an error: line naming the full queue |
Retry-After |
If the request carried Expected-Csn, a resend after a contention 503 can still be refused for a mismatch if another write landed meanwhile. The Terse-Csn on the 503 is the head at the moment of refusal.
Change the request#
These statuses are refusals. Sending the same request again produces the same answer, so none of them carries Retry-After.
| Status | When | First line of the body | What to change |
|---|---|---|---|
400 |
A header or parameter could not be what it claims, or the body is not valid UTF-8. | error: the Terse-Seam header is not a usable seam token; … · error: the Expected-Csn header must be a non-negative integer · error: send Terse-As-Of-Csn or Terse-As-Of, not both · error: send the address's @ suffix or the … header, not both · error: the Terse-Agent header must … · error: the Terse-Idempotency-Key header … · error: the request body is not valid UTF-8 · error: an Issue with Terse-As-Of-Csn or Terse-As-Of is queries only; the past is read-only · a sentence naming the history or load parameter |
Correct the named header, parameter or body. |
409 |
A write to a namespace marked read-only. Only a key that could otherwise write receives it. | error: namespace X is read-only (# Meta(readOnly) in its companion); its admin lifts it |
Ask the namespace's admin to lift the flag. Queries-only Issues are still served. |
409 |
A second load on a namespace that is already loading. | error: TERSE-LOAD-003: namespace X is already being loaded (load …); nothing was processed |
Wait for the running load to finish. |
409 |
A fork would exceed the plan's namespace limit, or playback would exceed its session limit. | this plan allows N namespaces; delete one to create another, or the playback limit's sentence |
Delete a namespace, or close a playback session. |
413 |
The body is larger than the plan's request-size limit, judged from Content-Length before the body is read or while a chunked body is read. |
error: the request body exceeds this tenant's limit of N bytes; nothing was processed |
Send a smaller request, or use /load for a large file. |
413 |
A line, a name, a header payload or a text value is over a content limit. | error: TERSE-LIM-00x: …; nothing was processed. It begins "…" |
Change the value; see TERSE-LIM. Splitting the request does not help. Carries Terse-Diagnostics and Server-Timing, no Terse-Csn. |
413 |
A load whose declared Content-Length is over the deployment's load limit. |
error: TERSE-LOAD-001: the load body is over N bytes (…); nothing was processed |
Load a smaller file. |
422 |
A point-in-time read before the first entry. | error: the Terse-As-Of time is before the first entry of this namespace; the first entry is csn 1 |
Ask for a later point. |
422 |
A point-in-time read too far from the nearest checkpoint for the deployment to serve. | a sentence naming the nearest checkpoint's CSN | Ask for a point nearer to the CSN it names. |
422 |
A structural directive the service cannot carry out as written. | error: TERSE-STO-002: <sentence>; nothing was committed |
Rewrite the declaration as the sentence says. |
422 |
A Terse-Idempotency-Key already used for a different body. |
error: TERSE-IDM-001: the Terse-Idempotency-Key was used for a different write, committed at csn N; a key names one body - send a new key for a new write; nothing was committed |
Send a new key for a new write. |
507 |
The namespace is at the plan's namespace-size limit and the declarations could grow it. | error: namespace 'X' is at its plan's limit of N bytes; nothing was processed |
Remove data, or move to a plan with a larger limit. A request of up to 1 MiB whose declarations only remove is still accepted. |
Every refusal on this page whose body ends ; nothing was processed or ; nothing was committed applied nothing: no CSN was spent and no query in the request was answered.
When the outcome is unknown#
Two statuses mean a write may or may not have committed. The caller must find out before resending, or resend in a way that cannot apply twice.
| Status | When | First line of the body | Headers |
|---|---|---|---|
500 |
The write failed at or after its commit point. | error: TERSE-STO-003: the write may have committed at csn N: resend with the same Terse-Idempotency-Key (safe), or read the head and resend with Expected-Csn (refused if it landed) |
Terse-Diagnostics, Server-Timing; no Terse-Csn, no Retry-After |
504 |
The request did not answer within the deployment's request time limit. | error: TERSE-REQ-001: the request did not answer within N seconds; the write may have been applied: read the head CSN before resending, and resend with Expected-Csn for exactly-once |
none |
After a 504 the Issue continues to its outcome and is recorded when it lands. When the request timed out before it was processed, the body ends ; nothing was processed instead, and the request can be resent. /load and /export are not subject to the time limit.
There are two ways to resend safely:
- Resend with the same
Terse-Idempotency-Key. If the first attempt committed, the resend is answered from the record withinfo: duplicate of csn N; not re-appliedand status200; otherwise it is applied. This is exact and is the method to prefer. Send the key on every write that may need a resend. - Read the head and resend with
Expected-Csn. Send a queries-only Issue, readTerse-Csn, check whether the write is present, and resend withExpected-Csnset to that CSN. If the first attempt lands in between, the resend is refused with anExpected-Csnmismatch in a200and nothing is applied twice.
An export that fails while its state is being read answers 500 with the read's error: line.
Stop#
| Status | When | First line of the body | What to do |
|---|---|---|---|
403 |
The account that owns the namespace is suspended. Applies to reads, writes, history, export, load, the admin routes and GET /v1/ns. |
error: this account is suspended; sign in to the portal for details; nothing was processed |
Sign in to the portal. See Account. |
404 (empty) |
The request addresses nothing this caller may see. | empty | Check the namespace name, the key and its grants. |
404 |
A seal or scrub that does not exist, asked for by a caller entitled to see it. | error: namespace X has no seal at csn N; the newest checkpoint is csn C, or error: namespace X has never been scrubbed; … |
Ask for a CSN that is sealed, or POST a scrub first. |
The empty 404#
The empty 404 is status 404 with an empty body and none of the service's headers. It is the same bytes for every one of these cases:
- a route or namespace that does not exist, including a route this deployment does not offer;
- a namespace name ending in
_meta; - no key, or a key that is malformed, unknown, revoked, expired, or belongs to another account;
- a key the namespace's grants admit to nothing;
- a key that is not an admin, on a route only an admin may call, whatever its parameters;
- an unknown or closed playback session, or a fork that is not a fork of the namespace named.
A caller without access therefore cannot tell whether the namespace exists, whether the key is valid, or what the key lacks. The owner of the namespace can see which case occurred in the account's log; see Logs.
Answers without a body#
Two answers have no body. One is the empty 404. The other is a 413 with an empty body, which means the request was larger than the deployment accepts for any account, a limit above every plan's request-size limit. Send a smaller request.
The order of checks#
The Issue route makes its checks in a fixed order, and the first that fails decides the answer. A caller that fails an early check learns nothing about the later ones; for example, an unadmitted caller never sees a 429 or a 403.
- The namespace name and the route: the empty 404.
- The key: the empty 404.
- Whether the grants admit the key to anything: the empty 404.
- Whether the account is suspended:
403. - An exclusive load with
Terse-Load-Exclusive: all:503. - The plan's request windows and the declared
Content-Length: a wait, then429or413. - The in-flight limits:
429or503. - The headers and the body:
400or413. - A write to a read-only namespace:
409. - An exclusive load with
Terse-Load-Exclusive: writes, for a request with declarations:503. - The plan's write windows:
429. - Processing:
200, or413,422,500,503or507.
The history, export and admin routes follow the same order with the checks that apply to them.