Skip to main content
Conventional HTTP status codes are returned to indicate the success or failure of an API request. Certain errors are retryable, meaning that re-issuing the same request after a delay could lead to a successful result. Exponential backoff is recommended.
In the context of an S2S append or read session, an error that occurs after a 200 OK status will be a “terminal message” on the response stream. However, pre-flight errors are sent normally.

Standard Errors

A standard error body has the following JSON form:
{
  "code": "brief_reason",
  "message": "more information about the error"
}
CodeHTTP StatusRetryableSide Effect
bad_header400NoNo
bad_path400NoNo
bad_query400NoNo
bad_json400NoNo
bad_proto400NoNo
bad_frame400NoNo
invalid422NoNo
permission_denied403NoNo
quota_exhausted403NoNo
basin_not_found404NoNo
stream_not_found404NoNo
access_token_not_found404NoNo
request_timeout408YesMaybe
resource_already_exists409NoNo
basin_deletion_pending409NoNo
stream_deletion_pending409NoNo
transaction_conflict409YesNo
rate_limited429YesNo
other500YesMaybe
storage500YesMaybe
hot_server502YesNo
unavailable503YesNo
upstream_timeout504YesMaybe
Requests that fail with 404 or 409 will succeed on a future attempt once the underlying condition changes (e.g., resource is created, or deletion completes).

Structured Errors

Append Condition Failed (412)

See append concurrency control for more context.
{
  "fencing_token_mismatch": "the-actual-fencing-token"
}
The current fencing token did not match the expected fencing token, which is returned.

Starting Point Out of Range (416)

416 without a Range header? Unconventional, but the shoe fits.See the precise conditions under which this is returned in response to a read request.
{
  "tail": {
    "seq_num": 42,
    "timestamp": 1767996832000
  }
}
The tail field indicates the current end position of the stream.