Skip to main content

Error codes

Every failure carries a stable code in the problem document's type, prefixed with urn:ocs:error:. Branch on the code. Message text is written for operators and changes without notice.

{
"type": "urn:ocs:error:core::gatekeeper::required",
"title": "This action requires step-up verification.",
"status": 403,
"traceId": "00-4e1b3e1e6ac01aa6ddbea28723e785d5-693a598807918896-00"
}

Codes are grouped by domain. The domain names are internal service names and are stable.

General

CodeStatusMeaning
core::error500Unexpected server error
core::request::invalid400Malformed or invalid request
core::access_denied401, 403Not authenticated, or missing the required scope

Users

CodeStatusMeaning
core::users::not_found404No such user
core::users::status::locked423Account locked
core::users::status::unverified403KYC not complete
core::users::kineto::balance::fail500Balance could not be read
core::auth::unavailable503Identity provider unavailable
core::auth::synthdetected::email409Email already registered

Transactions (kineto)

CodeStatusMeaning
core::kineto::unavailable503Ledger engine unreachable. Nothing was written
core::kineto::not_found404No transaction for that reference
core::kineto::deposit::initiate::fail400Deposit refused
core::kineto::deposit::confirm::fail400Confirmation refused, for example wrong state
core::kineto::p2p::initiate::fail400Transfer refused. Reason follows the last colon
core::kineto::p2p::self::blocked400Sender and recipient are the same
core::kineto::p2p::system_program::blocked400Recipient is the platform account
core::kineto::purchase::initiate::fail400Purchase refused
core::kineto::purchase::amount::invalid400Amount is not a positive number
core::kineto::purchase::merchant::invalid400Merchant unknown or not active
core::kineto::purchase::card::unsupported400Card path not available for this purchase
core::kineto::withdrawal::initiate::fail400Withdrawal refused
core::kineto::dispute::raise::invalid400Transaction cannot be disputed in its current state
core::kineto::dispute::raise::fail500Dispute could not be raised
core::kineto::dispute::resolve::fail500Resolution failed

Refusals such as insufficient balance arrive under the operation's initiate::fail code, with the reason in the message after the last colon. See Transactions overview.

Step-up (gatekeeper)

CodeStatusMeaning
core::gatekeeper::required403Enrolled user, no valid grant. Ask for a code and retry
core::gatekeeper::enrol::required403Action requires two-factor and the user has none. Route to enrolment
core::gatekeeper::code::invalid400Code rejected. Covers wrong, not enrolled and locked out alike
core::gatekeeper::totp::already_enrolled409Already enrolled
core::gatekeeper::enrol::fail500Enrolment state not written. Retry is safe
core::gatekeeper::grant::invalid503Verification temporarily unavailable

Cards and terminals (tessera)

CodeStatusMeaning
core::tessera::not_found404Unknown card, or not the caller's
core::tessera::type::invalid400Unknown card type
core::tessera::request::invalid400, 409Invalid request, or the card's state does not allow it
core::tessera::state::invalid409Card is in the wrong state for this action
core::tessera::limits::invalid400Cap combination rejected. Message is safe to show
core::tessera::issue::fail500Card could not be issued
core::tessera::update::fail500Card could not be updated
core::tessera::unusable400Card cannot pay, for example frozen
core::tessera::terminal::not_found404Unknown terminal
core::tessera::terminal::invalid400Invalid terminal request
core::tessera::terminal::already_registered409That UID is registered already
core::tessera::terminal::update::fail500Terminal could not be updated

Disputes (tribunal)

CodeStatusMeaning
core::tribunal::case::not_found404Unknown case, or the caller is not a party
core::tribunal::case::already_open409A case is already open for that transaction
core::tribunal::case::closed409The case is resolved and read-only
core::tribunal::case::list::fail500Cases could not be listed
core::tribunal::message::invalid400Empty or oversized message
core::tribunal::message::create::fail500Message could not be saved
core::tribunal::participant::invalid403Caller is not a party to the case

Platform (vault)

CodeStatusMeaning
core::vault::totp::create::fail500Authenticator key could not be created
core::vault::totp::delete::fail500Authenticator key could not be removed
core::vault::totp::validate::fail503Code could not be checked
core::vault::secret::get::fail500Secret read failed
core::vault::secret::write::fail500Secret write failed

Handling advice

ClassWhat to do
400 refusalsShow the reason. Do not retry unchanged
401Refresh once, then re-authenticate
403 step-up codesFollow step-up verification
403 othersThe user lacks the scope. Hide the control
404Treat as absent, not as an access error. The API answers 404 where confirming existence would leak information
409Re-read the resource, its state moved
500Nothing changed unless the message says otherwise. Safe to retry once
503A dependency is down. Back off and retry

Always capture traceId from failures. It identifies the request in our logs.