OriginChain docs
reference · errors

Error reference

Every non-2xx response from the OriginChain API has a JSON body with a stable error code, a human-readable message, and a retry flag that tells you whether the SDK should retry automatically.

// Every error response looks like this:
{
  "error": "schema_not_found",
  "message": "no schema registered under 'shop.orders'",
  "retry": false
}

Switch on the error code in your application, not on the message - codes are stable across versions; messages are tuned for humans and may change.

Client errors (4xx).

Your request was malformed, unauthorized, or referred to something that doesn't exist. Fix the request; don't retry blindly.

Code HTTP What it means How to fix
invalid_body 400 Request body couldn't be parsed. Check Content-Type matches the body (application/json for JSON, text/plain for TOML schemas, application/x-ndjson for streaming inserts).
type_mismatch 400 A column value doesn't match the declared column type. Check the error message - it names the offending field. Common: sending a string for an i64 column, or a number for a str.
missing_required 400 A column declared `required = true` was omitted from a row write. Send a value for every required column. Schema reference shows which columns are required.
fk_violation 400 A foreign key references a row that doesn't exist. Insert the target row first, or remove the foreign-key constraint if you really want orphan references.
check_violation 400 A row failed a CHECK constraint. Inspect the row's values against the constraint expression. The error message names the failing constraint.
dim_mismatch 400 A vector's length doesn't match the table's locked dim. Every vector in a table must have the same dim. The first put sets it.
metric_mismatch 400 A vector put used a different metric than the table's locked metric. Pick one of cosine / dot / l2 / manhattan and use it for every put + topk on the table.
unsupported_sql 400 The SQL statement contains a construct that isn't yet implemented. See SQL reference for the supported surface. Common: ORDER BY, HAVING, OR in WHERE, window functions, CTEs.
validation_failed 400 Generic catch-all for malformed input. Read the message field - it always names the specific problem.
unauthorized 401 Missing, malformed, or unknown bearer token. Check your Authorization header. See Auth reference.
forbidden 403 Token valid but doesn't have access to this resource. Usually means the token belongs to a different instance. Check endpoint hostname matches the token.
addon_required 402 Endpoint requires a paid add-on that isn't enabled. Enable the add-on in the dashboard, or call the alternative endpoint that doesn't need it.
schema_not_found 404 No schema is registered under the given name. Register the schema first - POST /v1/tenants/:t/schemas with the TOML manifest.
row_not_found 404 GET /rows/:schema/:pk for a primary key that doesn't exist. Verify the pk. If the row was deleted, this is the expected response.
conflict 409 ?expect=insert was set and the row already exists. Either drop the expect param (will overwrite) or update via the normal write path.
rate_limited 429 Per-key request budget exceeded. Honor the Retry-After header. See Rate limits reference.

Server errors (5xx).

Something went wrong on our side. Retry with exponential backoff. The SDKs do this automatically (up to 3 attempts by default).

Code HTTP What it means How to fix
internal_error 500 Server-side bug - the engine hit something it didn't expect. Retry once. If it persists, file a support ticket with the X-OC-Trace-Id from the response headers.
service_unavailable 503 The engine is temporarily unable to serve the request (often during failover or migration). Retry with exponential backoff. The SDKs do this automatically up to 3 retries.
gateway_timeout 504 Upstream timeout (replication ack didn't arrive in budget). Retry. If persistent, check the instance's replication health in the dashboard.

Retry strategy.

The SDKs already implement the right policy. If you're using raw HTTP, follow the same pattern:

  • 429: read the Retry-After header (seconds), wait that long, retry.
  • 500, 502, 503, 504: exponential backoff (0.25s, 0.5s, 1s, 2s, capped at 4s). Maximum 3 retries.
  • All 4xx except 429: do not retry. The request is malformed; retrying won't help.
  • Idempotency: the SDKs auto-attach an Idempotency-Key header on every mutating call, so retries don't double-insert.

For implementation details, see Rate limits.