跳转到内容

Error codes

canonical: spec/v1/artifacts/registry/error-code-registry.json · catalog version 2026-10-09.4

code kind HTTP scope / applies to description
aad_digest_mismatch code 422 both Encrypted envelope AAD digest does not match the canonical normalized AAD.
abuse_network reason_code — moderation_decision Cross-Realm abuse network signal aggregated by moderation server.
abuse_review reason_code — moderation_decision Awaiting moderator review.
account_binding_principal_mismatch reason_code — identity_creation, client_validation The authenticated service account is already bound to a principal_id different from the DID locally derived from the frozen identity-creation draft. The client MUST fail closed, visibly disclose the conflict, and MUST NOT adopt the returned principal or silently regenerate a replacement identity.
account_deactivated code 401 both The principal account is deactivated. Existing session grants are invalidated and protected requests MUST fail closed; new session issuance MAY surface the same code with a 403 policy-denial status.
account_erased code 401 both The principal account is in terminal erasure_pending state. Existing session grants are invalidated and protected requests MUST fail closed with this code instead of a generic unauthenticated response.
account_locked code 401 both The principal account is locked. Existing session grants are invalidated and protected requests MUST fail closed; new session issuance MAY surface the same code with a 403 policy-denial status.
account_status_binding_rollback reason_code — account_status, service_call, state_resolution A Station received an otherwise valid AccountStatusRecord whose binding_version is lower than the durable floor for the same Account Authority and account. The receiver MUST return failed_precondition with this reason, perform zero replica/outbox/erasure-intent writes, and MUST NOT retry the same record. See zh/identity/account-lifecycle.md §3.
account_status_record_fork reason_code — account_status, service_call, state_resolution A Station received an AccountStatusRecord that conflicts with the issuer-ledger chain: either the durable status_seq already names a different record, or the next status_seq does not name the durable head as previous_account_status_record_id. The receiver MUST return failed_precondition with this reason, perform zero writes, stop automatic retry or gap recovery for the conflicting record, and quarantine/alert for operator investigation. It MUST NOT reuse duplicate_conflict, which is reserved by this operation for Idempotency-Key reuse with different canonical request bytes. See zh/identity/account-lifecycle.md §3.
account_status_record_stale reason_code — account_status, service_call, state_resolution A Station received an otherwise valid AccountStatusRecord whose status_seq is lower than its durable replica head. The durable head is the only comparison baseline, so this reason applies even when the submitted record is byte-identical to a history row the receiver still stores for that status_seq; a retained history row MUST NOT downgrade the outcome to duplicate. The receiver MUST return failed_precondition with this reason, perform zero writes, and treat the exact record as terminal/non-retryable. duplicate is reserved for a submission whose status_seq and record identity both equal the durable head. The full ordered classification is registry/account-status-replica-decision-table.json. See zh/identity/account-lifecycle.md §3.1.
account_status_transition_invalid reason_code — account_status, event_envelope, state_resolution An Account Authority issuer-ledger mutation requested a `from → to` status transition not permitted by the account-status legal-transition table — e.g. reactivating a `deactivated` account. The current-head transaction MUST fail with zero account-row/ledger/audit/outbox writes. A successor after `erasure_pending` uses the more specific `erasure_pending_is_terminal`. See zh/identity/account-lifecycle.md §3.
account_suspended code 403 both The principal account is suspended. Existing sessions may observe account state where permitted, but new session issuance and writes MUST fail closed with this code.
accountability_grant_missing reason_code — event_envelope, auth_decision, service_call Returned in three surfaces. (1) `event_envelope` / `auth_decision`: an Actor Profile update declares an `accountable_principal_ids[]` entry without a corresponding active `ak.identity.accountability_grant` (issuer=that DID, subject=profile.principal_id, grant_status=active, within validity window). Reducer MUST reject the entire Event with this reason and MUST NOT accept a field-stripped projection. See zh/models/actor.md §3.3.1. (2) `service_call`: returned by orchestrator HTTP operations that fan-out an accountability grant — `ak.self.agent.command.provision.v1` rejects when the controller cannot present an issuable accountability grant for the new agent principal, and `ak.self.agent.command.resume.v1` rejects when the controller's accountability grant over the agent has been revoked or has lapsed its freshness window since `ak.self.agent.command.pause.v1`. HTTP callers MUST treat this as a precondition-class failure, not transient.
actor_signature_revoked reason_code — event_envelope, auth_decision An event was signed with a device key that the deactivation/lock fanout has marked revoked. Subsequent ak.self.events.command.submit.v1 signed by that device MUST be rejected. See zh/identity/account-lifecycle.md §7.1.
aead_nonce_counter_replay reason_code — event_envelope, encoding An AEAD-encrypted payload (encrypted_payload, blob attachment, to_device, etc.) repeated a per-(key_ref, epoch, device_id) counter already seen by the receiver. The receiver MUST reject the payload before AEAD decryption to prevent attempted nonce reuse against a valid sender device. See zh/crypto-media/media-and-blob.md §3.1 and zh/conformance/encoding.md §10.1.
aead_nonce_derivation_invalid reason_code — event_envelope, encoding An AEAD nonce on the wire does not match the deterministic derivation from MLS-Exporter context {key_ref, epoch, purpose} plus (device_id, monotonic counter) mandated by zh/crypto-media/media-and-blob.md §3.1. Producers MUST NOT emit naive random nonces under shared MLS application keys; receivers MUST reject such payloads to enforce the cross-implementation nonce-uniqueness contract.
agent_authorization_conflicted code 409 both The accepted Agent key component contains conflicting active authorization state at the target checkpoint. The Event and signer evidence MUST be quarantined.
agent_authorization_inactive code 422 both The target Event accepted-at lies outside the Agent key authorization validity interval because the authorization is revoked, superseded, or expired.
agent_deactivated reason_code — auth_decision, service_call, event_envelope A request targeted an Agent principal whose current `agent_status` typed current result is `deactivated` (terminal). The endpoint MUST fail closed and no resume path exists. The accepted parent lifecycle witness is sufficient to make all subordinate authorization ineffective; asynchronous cleanup need not synthesize key/grant revoke Events and cannot restore authority. Callers MUST NOT treat this as transient. See zh/identity/key-management.md §3.6.1.
agent_grant_exceeds_requested_scope reason_code — event_envelope, auth_decision, service_call A Agent Realm grant contains an action or resource not covered by the Agent's immutable provision requested_scope, or attempts to omit or relax a mandatory provision constraint. Grant attach and reducer admission MUST fail closed with failed_precondition; Realm membership, policy, participation, pairing or key authorization cannot restore authority omitted at provision time. See zh/authz/capabilities.md section 9.1 and zh/identity/key-management.md section 3.6.1.
agent_key_authorization_expired reason_code — auth_decision Agent session issuance rejected because the referenced ak.agent.key.authorize declared an expires_at that has elapsed. Distinct from proof_invalid (malformed / unverifiable proof): the runtime should prompt the controller to re-authorize the same key (same-key re-authorization, zh/identity/key-management.md §3.6) rather than rebuild the proof. Never returned for non-expiring (absent expires_at) authorizations.
agent_key_scope_reauthorization_required reason_code — auth_decision, service_call The immutable provision ceiling contains every operation required by the selected runtime capability, but the accepted Agent key authorization omits one or more of them. The operation fails with failed_precondition; the controller may re-authorize or rotate the key only within the immutable provision ceiling. See zh/identity/key-management.md §3.6.1 and agent-runtime-scope-registry.json.
agent_mls_leaf_binding_mismatch code 422 both An ordinary encrypted Agent Event does not have exactly one historical active BasicCredential leaf whose identity, signature key, and admission authorization lineage match its Agent signer evidence.
agent_participation_ceiling_unresolved reason_code — event_envelope, auth_decision, service_call An Agent action or mention fanout requires the current target-local deployment/Realm/Circle/Strand participation policy, but one or more required layers are stale, unavailable, or unverifiable. The action-time gate treats the unresolved policy as all false. The controller's private selection remains stored unchanged. See zh/authz/capabilities.md §5.4.
agent_participation_ceiling_widen reason_code — state_resolution Sub-reason for failed_precondition when a Realm/Circle/Strand agent_participation ceiling write would widen (enable a bit disabled by) its parent ceiling. The deployment ⊇ Realm ⊇ Circle ⊇ Strand ceiling chain is tighten-only (monotone). See zh/models/realm-and-space.md, zh/models/circle.md, zh/authz/capabilities.md §5.4.
agent_paused reason_code — auth_decision, service_call, event_envelope A request targeted an agent principal whose current `agent_status` typed current result is `paused`. Auth Server MUST reject new agent session grants, and any submit / sidecar / grant-management call by or for the paused agent MUST fail closed until `ak.self.agent.command.resume.v1` lands. Distinct from `capability_denied` so callers can surface the recoverable lifecycle state. See zh/identity/key-management.md §3.6.1.
agent_pcr_genesis_declaration_conflict reason_code — service_call, event_envelope A second ak.agent.provision declared a principal_control_realm_id that another accepted provision already claims. Inside one controller PCR the commit-ordered projection claim typed current result rejects it; across controllers the Station's local uniqueness index rejects it. Either way the write set is empty and the earlier claim is untouched. See zh/identity/key-management.md §3.6.3.
agent_pcr_genesis_declaration_missing reason_code — pcr_genesis, event_envelope A agent_control ak.realm.create was submitted without an already accepted ak.agent.provision in the controller PCR whose payload.principal_control_realm_id equals retype(this genesis event_id). The genesis carries no ref to its provision, so this reverse look-up is the whole binding: no match MUST fail closed with zero writes, and the receiver MUST NOT materialize the Realm, the agent-status transition or any partial projection. See zh/identity/key-management.md §3.6.3.
agent_provision_fanout_unavailable code 501 endpoint Agent provisioning fanout is not available on this deployment.
agent_provision_scope_migration_required reason_code — auth_decision, service_call The Agent's immutable provision requested_scope omits an operation mandatory for the selected runtime capability. The operation fails with failed_precondition and recovery requires provisioning a new Agent principal; key re-pairing, Realm grants and session issuance MUST NOT widen this ceiling. See zh/identity/key-management.md §3.6.1 and agent-runtime-scope-registry.json.
agent_provisioning_already_declared reason_code — event_envelope, service_call A second ak.agent.provision declared an agent_id that an accepted provision in this controller PCR already carries in the agent_provisioning family. The write set is empty and the earlier fact is untouched. The realm-id claim cannot catch this case: a second provision freezes a different genesis create, so it declares a different principal_control_realm_id and conflicts with nothing. Re-declaring one agent_id is how the immutable requested_scope ceiling would be widened, which zh/identity/key-management.md section 3.6.1 answers with provisioning a new Agent principal instead. See zh/identity/key-management.md section 3.6.3.
agent_reply_not_permitted reason_code — state_resolution An Agent attempted to author ak.message.create in a scope where current controller selection and current target policy do not both enable reply_message. See zh/authz/capabilities.md §5.4 and zh/models/private-objects.md §4.1.
agent_requested_scope_commitment_invalid reason_code — event_envelope, auth_decision, service_call The complete immutable Agent requested_scope commitment is missing from accepted-at Agent DID history, differs from the service projection, or its domain-separated digest does not verify. Pairing, Realm grant admission and agent session issuance MUST fail closed and MUST NOT treat a service-local Agent row as the authority source. See zh/identity/key-management.md section 3.6.1.
agent_runtime_request_conflict reason_code — service_call A different stable runtime key binding was submitted while the same open pairing_request_id already has a pending runtime request. The service MUST return HTTP 409 and MUST NOT replace the current pending request, approval_request_id, or notification id. A retry with the same ak.agent.runtime_key_binding.v1 digest is idempotent and does not use this error. See zh/identity/key-management.md §3.6.2.
agent_session_scope_refresh_required reason_code — auth_decision, service_call The immutable provision ceiling and accepted Agent key authorization both contain every operation required by the selected runtime capability, but the requested or current session scope omits one or more. The operation fails with failed_precondition and recovery is a new session constrained by both upper ceilings. See zh/identity/key-management.md §3.6.1 and agent-runtime-scope-registry.json.
agent_signer_evidence_missing code 404 both Portable Agent signer evidence is unavailable for the authorized shared context. For callers without that context this response is indistinguishable from an unknown Agent or method. Consumers remain Unresolved and MUST NOT fall back to device directory or an ordinary-Realm MLS leaf.
agent_signer_evidence_stale code 409 both Agent signer evidence exists but its source freshness observation or state checkpoint is too old for the target Event admission. Consumers remain Unresolved/Stale and retry without promoting the Event to Verified.
agent_signing_key_mismatch code 422 both The Agent proof method, disclosed raw key, public-key digest, signing-binding digest, authorization Event, or controller proof do not form one exact binding.
applet_already_registered code 409 endpoint An applet with the same identity is already registered for the realm.
applet_e2ee_join_unauthorized code 403 endpoint An Applet, bot actor, or Applet-managed Ghost Actor attempted to join an E2EE Realm / MLS group without the independent E2EE join authorization required by ak.profile.applet_e2ee_join.v1. Ordinary message/write capability grants do not imply MLS join authority. See zh/extensions/applet-integration.md §12.
applet_effective_scope_mismatch code 404 endpoint The applet install projection does not match the requested effective scope.
applet_install_plan_mismatch code 409 endpoint ak.self.applet.command.install.v1 recomputed the canonical InstallPlan from the submitted Applet Package, caller-signed registration/capability-grant Events, effective_scope, and current Realm/Circle policy, and the recomputed plan_digest did not exactly match the submitted plan_digest. Server MUST fail closed and require a fresh preview/approval before formal Event admission. See zh/extensions/applet-integration.md §4b.
applet_install_projection_incomplete code 409 endpoint The applet install projection is not yet complete.
applet_install_required code 409 endpoint The operation requires the applet to be installed first.
applet_managed_actor_provision_invalid reason_code — event_envelope, auth_decision An ak.applet.managed_actor.provision Event in the closed Applet managed-actor creation aggregate does not satisfy its binding rules: actor_id.account_id.station_id is not the receiving Station, the actor collides with the service or controller principal, or the provisioned independent Bot/Ghost does not match the signed authoring request, accepted Applet registration, role and effective scope. See zh/extensions/applet-integration.md.
applet_managed_pcr_genesis_invalid reason_code — pcr_genesis, event_envelope The purpose=applet_managed_control PCR genesis Event in the Applet managed-actor creation aggregate does not cross-bind its provision Event, initial_resolution, Applet, grant and service verbatim. See zh/extensions/applet-integration.md.
applet_managed_pcr_genesis_requires_closed_aggregate reason_code — pcr_genesis, federation_transaction A purpose=applet_managed_control PCR genesis arrived outside the closed Applet install / Ghost provisioning aggregate - an ordinary submit, a Realm bootstrap batch, or ak.peer.events.command.submit.v1. Transport and proof validity do not make it an AppletFormal admission. See zh/extensions/applet-integration.md.
applet_namespace_conflict code 409 endpoint The applet namespace conflicts with an existing registration.
applet_namespace_mismatch reason_code — state_resolution, auth_decision Sub-reason for a delegated-handoff Event rejection when auth_data.executed_by is not within the applet_id registration's declared service / bot DID set or namespaces.actors pattern. Prevents a grant scoped to one applet from being exercised under an unrelated applet_id. See zh/extensions/applet-integration.md §11.
applet_namespace_pattern_invalid code 400 endpoint A namespaces.actors pattern in the submitted Applet package or derived registration violates the actor namespace pattern shape: it is not a did:webvh pattern, its SCID segment is neither '*' nor a non-empty SCID, it pins the registration's own service SCID in the SCID segment so it can never match a compliant Ghost, its host segment is not a literal equal to the host of the bare did the service_id currently resolves to, or no segment follows that host. Install preview and install commit both fail closed. See zh/extensions/applet-schema.md 2 and zh/extensions/applet-integration.md 4.1.
applet_package_expired code 400 endpoint The submitted applet package has expired.
applet_registration_epoch_evidence_deactivated code 409 endpoint The exact DID method version pinned by the Applet registration epoch evidence resolves successfully but is deactivated. Preview and authoring fail closed without unversioned refetch or service-local key fallback.
applet_registration_epoch_evidence_mismatch code 400 endpoint Applet registration epoch evidence does not match the expected epoch.
applet_registration_epoch_evidence_missing code 400 endpoint Applet registration epoch evidence is missing.
applet_registration_epoch_signing_key_mismatch code 400 endpoint Applet registration epoch signing key does not match the registered key.
applet_registration_unauthorized code 403 endpoint An Applet registration or transaction attempted to enter a Realm without an explicit grant from the Realm owner, Realm admin, or Realm-policy-authorized administrator actor, as checked by the Station authorization capability. Namespace claims and self-signed applet registration are insufficient. See zh/extensions/applet-integration.md §4.
applet_revoked code 403 endpoint A revoked effective Applet install attempted a future write, transaction push side effect, delegated action, widget token use, or E2EE join. Reducers and service-call handlers MUST fail closed after ak.self.applet.command.revoke.v1 / ak.capability.revoke has taken effect. See zh/extensions/applet-integration.md §4b. Inbound transaction with a matching revoked install returns this code; never-authorized, absent or mismatched installs return applet_registration_unauthorized.
applet_transaction_in_progress code 409 endpoint Another applet transaction is already in progress.
approval_already_consumed reason_code — event_envelope, auth_decision An agent draft/action approval has already been consumed by a successful publish attempt. Replaying the same approval MUST fail closed instead of publishing twice. See zh/conformance/conformance-vectors.md.
approval_carrier_unregistered reason_code — auth_decision, event_envelope A grant approval constraint or ak.policy.action approval requirement targets a capability action whose approval_requirement_eligibility is ineligible_no_registered_carrier. The governance Station rejects the authoring Event at write admission with top-level schema_violation (HTTP 422), this reason_code, and zero Event/RealmCommit/current-result effects. The canonical eligibility registry is capability-action-registry.json; the direct producers are ak.self.events.command.submit.v1 and ak.peer.events.command.submit.v1 authority_forward, with ak.self.applet.command.install.v1 covering its grant Event. See zh/authz/constraint-schema.md section 9.1 and zh/models/governance-objects.md section 3.4.
approval_nonce_reused reason_code — event_envelope, auth_decision An approval signature whose (approval_context, approver_did, nonce) triple was already consumed by a successfully accepted target was presented for a different target. The nonce namespace is (approval_context, approver_did) and the nonce is consumed only when the target is accepted, in that same transaction: an exact replay of the already accepted target returns the original outcome, and a failed verification or an unmet quorum MUST NOT consume it early, so normal retries that collect the remaining votes still work. See zh/authz/constraint-schema.md section 9.2.
approval_required reason_code — event_envelope, auth_decision An eligible execution was rejected because approval evidence is required and what was supplied through its registered carrier does not meet the requirement. Two independent layers can raise that requirement and both are evaluated: an approval constraint on a matched capability grant (zh/authz/capabilities.md §6 / §8, zh/authz/constraint-schema.md §9), and the Realm governance approval configuration registered as the policy_action typed current result (zh/models/governance-objects.md §3.5), which hangs off an (action token, scope) pair rather than off one grant. Either layer alone is enough to produce this reason code, and a layer writing approval_required=false only withdraws its own demand -- it never cancels the other's. The top-level error is claim_required. This is a require_review-class outcome, not a deny: supplying the missing approval signatures through the carrier named by capability-action-registry.json and retrying is the defined path. Requirements for actions without a registered carrier are instead rejected at configuration write time with approval_carrier_unregistered.
audience_mismatch code 400 endpoint Session-grant rotation requested an audience different from the grant's bound audience. Audience MUST NOT change across rotation.
audience_unknown code 404 endpoint A token, invite, notification, or delivery request names an audience that is unknown or not visible to the caller.
audit_capability_incomplete reason_code — auth_decision Reading the full per-Strand watch state (including `muted` entries) requires both `ak.realm.notification.audit` and `ak.audit.accessed` capabilities; one was missing. See zh/models/strand-and-message.md §8.5.
audit_receipt_invalidated code 409 both An auditable E2EE decrypt receipt was invalidated by backfill, witness, or state verification.
auth_expired code 401 both Session, token, or grant has expired.
authoring_request_expired code 410 endpoint A new authoring attempt arrived after its registered preparation expiry. Message prepare uses client created_at plus 300 seconds. The caller needs a new request identity; accepted Event validity and exact replay/recovery of an existing submission are unaffected.
authority_cycle reason_code — event_envelope, auth_decision A ak.capability.grant would close a cycle in the authority graph, traversed as a DFS over grant_id edges taken from issuer_authority_refs entries with kind=grant. realm_root refs are rooted terminals and contribute no edge. Reducer MUST reject the grant; evaluation MUST NOT recurse without terminating. See zh/authz/capabilities.md §10.
authority_expiry_widening reason_code — event_envelope, auth_decision For some action this grant claims, its effective window is wider than the refs that cover that action allow: it starts before the earliest effective_not_before among them, or ends after the latest effective_expires_at. The bound is evaluated per action, because a global min/max would let an action covered only by a late-window ref borrow an early one. See zh/authz/capabilities.md §10.
authority_regrant_denied reason_code — event_envelope, auth_decision A grant was issued from a ref carrying authority_regrant_allowed=false, or declares a max_authority_depth above what its refs leave. With authority_regrant_allowed=false the child's max_authority_depth MUST be 0 and no further grant may name it. See zh/authz/capabilities.md §6 / §10.
authority_scope_custom_unsupported reason_code — event_envelope, auth_decision A grant declared `authority_scope=custom`, which v1 does not define an evaluable semantics for. The reducer MUST reject (schema_violation) until a future profile assigns custom-scope evaluation rules. See zh/authz/constraint-schema.md §7.
authority_scope_mismatch reason_code — event_envelope, auth_decision A child grant violated its issuer authority's `authority_scope`: `narrowing_only` requires the child resources/actions to be a strict-or-equal subset that narrows at least one axis, and `same_scope` requires the child to match the issuer authority's scope exactly. The reducer MUST reject a child that exceeds or fails to satisfy the declared narrowing discipline. See zh/authz/constraint-schema.md §7.
authorized_grant_revoked code 409 both A pending write, cache entry, snapshot claim, or downstream grant depends on a grant that has been revoked, superseded, expired, or revoked through an ancestor grant. The dependent action MUST fail closed or be quarantined until re-authorized.
avatar_blob_ref_invalid code 422 endpoint `ak.self.account.command.update_profile.v1` received an `avatar_blob_ref` that is not a valid Arkret Blob reference, does not resolve under the caller's profile/avatar policy, or points to a blob the server cannot authorize for profile display. Protocol profile updates MUST use `avatar_blob_ref`; `avatar_url` is not a protocol field.
backend_unavailable reason_code — event_envelope, service_call The selected recording or transcription backend was unavailable.
backup_revision_stale reason_code — device_recovery, state_resolution `ak.schema.key_backup.v1.source_commit_ref.realm_commit_id` does not resolve to an accepted RealmCommit on the principal control stream, or `device_generation_ref` does not equal the active `current_device_generation_ref`. A later RealmCommit on the same stream does not by itself make the envelope stale. Receivers MUST refuse to use the envelope as the primary recovery source. See zh/identity/key-management.md §7.6.
blob_digest_mismatch code 422 endpoint Blob upload, head, download, or presign verification found that the transferred content digest does not match the declared digest.
blob_expired code 410 endpoint The referenced blob, upload slot, or presigned blob authority has expired.
blob_presign_invalid code 400 endpoint A blob presign request or presigned URL token is malformed, out of policy, expired, or fails integrity checks.
blob_quota_exceeded code 403 endpoint The blob operation exceeds actor, Realm, organization, or deployment storage/bandwidth quota.
blob_redacted reason_code — state_resolution Blob has been redacted (ak.redaction accepted) or hard-erased (ak.audit.erasure_receipt published) and is no longer fetchable. Both new presign requests and in-flight (not-yet-expired) presign URLs MUST be rejected with this code. See zh/crypto-media/media-and-blob.md §5.4.4.1.
calendar_activation_mismatch reason_code — event_envelope, schema_validation Sub-reason for schema_violation when Strand.schema_refs and the matching metadata.fields profile subtree do not co-occur on the post-patch object, in either direction. Applies to ak.schema.calendar_event.v1 with metadata.fields.calendar. See zh/models/calendar-event.md.
calendar_event_cancelled reason_code — event_envelope, auth_decision A new RSVP targets a Calendar Strand whose schedule status is cancelled. Historical RSVP projection is retained; new responses are refused. The generic Strand stage axis MUST NOT be reinterpreted as calendar status. See zh/models/calendar-event.md. This is an authoring-side and projection-side code for the same reason as calendar_schedule_unavailable: the cancelled status lives in the Calendar subtree plaintext.
calendar_schedule_unavailable reason_code — event_envelope, state_resolution An RSVP or occurrence expansion was attempted while the deterministic Calendar schedule winner is encrypted_unresolved rather than available. See zh/models/calendar-event.md. This is an authoring-side and projection-side code, never a server admission gate: deciding readability requires the Calendar subtree plaintext, so gating admission on it would fork the accepted set between e2ee and plaintext Realms.
calendar_tzdb_mismatch reason_code — event_envelope, service_call, projection The signed schedule tzdb_version is outside the receiver's executable release set declared in ServiceDescribe.calendar_tzdb_versions. The receiver MUST fail closed or mark instant projection unresolved and MUST NOT substitute a nearby or newer release. See zh/models/calendar-event.md.
call_already_answered code 409 service_call Call answer was already accepted and the operation is not idempotent for this participant.
call_expired code 410 service_call Call exists but its signaling window has expired.
call_moderation_unauthorised reason_code — service_call, event_envelope A v1 moderator action (kick / ban / end-for-all, via `ak.call.signal{moderation}` or a `ak.call.state` moderation field) was attempted by an actor lacking `ak.call.moderate`. Reducer / receiver MUST reject. Moderator force-mute is deferred in v1: a mute_state{by=moderator} is unsupported_feature and an ak.call.state mute_override is schema_violation before this authorization check.
call_not_found code 404 service_call Call does not exist or is not visible to the caller.
call_participant_removed reason_code — service_call A participant whose `(actor_id, device_id)` has an effective kick in `call_moderation`, or whose actor has an effective ban there, attempted to re-establish a media leg or re-issue a join token. Token issuer / SFU MUST refuse; a banned actor MUST NOT rejoin until the ban is lifted. See zh/crypto-media/webrtc-signaling.md §3a.
call_state_terminal reason_code — event_envelope An `ak.call.state` event attempted to transition `state_transition.from` out of a terminal value (`ended` / `missed` / `failed` / `cancelled`). Call lifecycle is monotonic; the reducer MUST `failed_precondition`. Capture lifecycles use orthogonal per-segment transition typed results. See zh/crypto-media/call-state.md §4.2.
call_state_transition_invalid reason_code — event_envelope A `ak.call.state` event requested a `state` transition from a non-terminal state that is not listed in the legal-successor table (transitions out of a terminal state use `call_state_terminal` instead). The reducer MUST `failed_precondition`. See zh/crypto-media/call-state.md §4.2.
cannot_pair_current_device code 409 endpoint The current device cannot pair with itself.
capability_denied code 403 both Capability, policy, or visibility rules deny the request.
cas_conflict code 409 both An optimistic concurrency precondition failed because the authority-committed typed current result or stream head no longer equals the submitted expectation. The caller must read current state and create a new signed Event; exact retry retains the original identity.
causal_conflict code 409 both An application-level referenced object, revision, or domain transition is incompatible with current authority-committed state. This code does not describe an Event predecessor graph.
cbor_bounds_invalid reason_code — encoding, schema_validation A hand-written deterministic CBOR structure (e.g. the mls_governance_binding GroupContext extension) violates v1 decode bounds: a single array/map declares or contains more than 65536 items, or a string / byte string / array / map header declares a length or item count exceeding the remaining input bytes (capacity bomb). Decoder MUST reject (top-level schema_violation) before allocating buffers sized from the declared length. See zh/conformance/scalability-constraints.md section 2.
cbor_not_deterministic reason_code — encoding, schema_validation A hand-written CBOR structure violates RFC 8949 section 4.2 deterministic encoding requirements: indefinite-length items (map 0xbf, array 0x9f, string 0x5f/0x7f), non-minimal length encoding, or unsorted map keys. Receiver MUST reject (top-level schema_violation) instead of normalising. See zh/conformance/scalability-constraints.md section 2 and zh/crypto-media/encryption-and-audit.md section 2.5.3.
challenge_expired reason_code — event_envelope, auth_decision A challenge proof was submitted whose issuance is older than `max_proof_age`. The reducer MUST reject with failed_precondition and MUST NOT auto-renew; the applicant must obtain a fresh challenge_id. See zh/governance/join-policy.md §3.1 and §4.
challenge_failed reason_code — event_envelope, auth_decision A join-policy challenge gate answer (e.g. CAPTCHA / proof-of-work / knowledge challenge) carried by a membership admission request failed verification.
challenge_proof_invalid reason_code — auth_decision, service_call A runtime challenge proof attached to `ak.member.state{join}.gate_proofs[]` fails verification (signature / freshness / verifier domain). Freshness here is the replay/binding freshness carried by the proof itself; a proof issued beyond max_proof_age is challenge_expired instead, and the two reasons are mutually exclusive. See zh/governance/join-policy.md §4.
circle_already_terminal reason_code — state_resolution Sub-reason for failed_precondition when a Circle lifecycle write targets a Circle that is already tombstoned or otherwise terminal. See zh/models/common-fields.md §5.1 and zh/models/circle.md §9.
circle_count_exceeded reason_code — event_envelope, state_resolution Reducer rejected a `ak.circle.create` exceeding the per-Realm active Circle cap, or a `ak.circle.member.state -> join` that would exceed the per-actor active MLS-backed Circle cap. Caps bound cascade/delivery fanout and the M+R MLS-rotation amplification of a single membership change (zh/conformance/scalability-constraints.md §5, zh/models/circle.md §10).
circle_member_must_be_realm_member reason_code — state_resolution Sub-reason for failed_precondition on ak.circle.member.state -> join when, in the accepting cut, the target actor's parent Realm member_state current is not `join` or its typed revision differs from the payload's parent_membership_revision. Circle.members ⊆ Realm.members is a hard invariant bound to the exact current parent join. See zh/models/circle.md §9.1.
circle_not_active reason_code — state_resolution Sub-reason for failed_precondition when scope_circle_id points at a Circle whose state is archived or tombstoned. See zh/models/circle.md §6.1.
circle_not_archived reason_code — state_resolution Sub-reason for failed_precondition when ak.circle.restore targets a Circle whose current lifecycle state is not archived. See zh/models/common-fields.md §5.1 and zh/models/circle.md §9.
circle_realm_mismatch reason_code — schema_validation, state_resolution Sub-reason for schema_violation when an object's scope_circle_id references a Circle whose realm_id does not match the object's realm_id. See zh/models/circle.md §6.1.
circle_short_name_taken reason_code — schema_validation, state_resolution, service_call Circle creation or display update failed the reducer-enforced case-insensitive uniqueness of display.short_name within (realm_id, short_name). See zh/models/circle.md §4.
claim_failed code 400 endpoint An atomic one-time key, pre-key, or KeyPackage claim failed. On privacy-sensitive claim surfaces this code deliberately collapses target absence, visibility, inventory, consent, policy, capability, freshness, and abuse-control failures into one non-enumerable outward result.
claim_generation_mismatch reason_code — crypto, auth_decision An MLS Welcome / KeyPackage claim binds a device generation that does not equal the receiver's current accepted generation. Receivers MUST reject before admitting the Welcome or key material. See zh/crypto-media/encryption-and-audit.md §2.6 and zh/crypto-media/device-lifecycle.md §14.
claim_invalid reason_code — event_envelope, auth_decision A claim, attestation, or invite / binding proof submitted for membership or invitation admission is malformed, unverifiable, or fails policy checks.
claim_required code 403 both A required claim, attestation, or presentation is missing.
conflict code 409 both A generic state conflict occurred.
consent_required code 403 service_call The holder requires explicit user consent before disclosing the requested presentation.
consent_revoked reason_code — auth_decision Authorization outcome when a cached consent decision is re-evaluated and the underlying consent has been revoked; the stale cache entry MUST NOT authorize the action. See zh/conformance/conformance-vectors.md §3.5 (ak.vector.consent.cache_invalidation.v1).
consent_withdrawn reason_code — event_envelope, state_resolution Required recording or transcription consent was withdrawn.
contact_lineage_conflict code 409 endpoint A Contact fact forks an issuer-local version, skips a version, references a non-current predecessor, reuses a consumed request ref, or attempts to revive a tombstoned generation. The conflicting fact is quarantined.
contact_request_expired code 409 both Sub-reason for failed_precondition when ak.self.contact.command.respond.v1 or ak.self.contact.command.reject.v1 targets a contact request older than contact_request_pending_ttl. The request projection is expired and no terminal response may be authored from it.
contact_request_not_pending code 409 both Sub-reason for failed_precondition when ak.self.contact.command.respond.v1 or ak.self.contact.command.reject.v1 targets a request that has already been accepted, rejected, tombstoned, withdrawn, or otherwise left the pending state.
contact_scope_stale code 409 endpoint An existing Contact binding is discoverable but the source-signed issuer head checkpoint/current lease is stale, unknown or incomplete. Contact-based create/send fails closed while coordinates remain visible to authorized participants.
continuity_evidence_unavailable code 409 endpoint A required bilateral continuity checkpoint, predecessor checkpoint or uncompressed tail segment is not currently available. The operation writes nothing and may be retried only after importing or retrieving the exact portable evidence; no gap is inferred or skipped.
continuity_invalid code 409 endpoint Bilateral continuity evidence has an invalid signature, root/participant mismatch, broken or trimmed edge, rollback, same-sequence fork, accumulator mismatch or one-sided checkpoint. The operation writes nothing and MUST NOT downgrade this result to evidence retrieval.
controller_signed_event_required code 400 endpoint An Agent operation that must preserve controller authorship omitted the required controller-signed durable Event proof. The service MUST NOT synthesize, service-sign, or directly project the missing controller fact. The controller must author and submit the exact closed Event required by the operation. See zh/identity/key-management.md §3.6.1 Lifecycle.
credential_expired code 410 service_call A credential matching the presentation request exists but is expired.
credential_not_found code 404 service_call The holder has no credential matching the authorized presentation request.
cross_domain_replay_rejected reason_code — identity_creation, proof_verification The signed proof audience, origin or trust_domain does not match the current request context; the verifier rejects it before any state transition.
cross_realm_structural_relation reason_code — event_envelope, auth_decision A structural `contains` Relation was submitted that would cross Realm boundaries. Structural containment (Board → List → Strand / Space hierarchy) MUST stay within a single Realm; cross-Realm links use the dedicated `ak.relation.*` non-structural kinds. See zh/models/relation.md §4.
current_did_authority_unavailable code 503 both A call site explicitly registered as current-DID-dependent cannot obtain fresh current authority. Unrelated human PCR operations remain available.
cursor_expired code 410 endpoint The opaque cursor (ak:cursor:...) has a valid shape but its `x` expiry is in the past. Client MUST request a fresh cursor (initial /account/subscribe, /snapshot/head, or new write barrier).
cursor_integrity_invalid code 400 endpoint Cursor integrity check failed for the v1 stateful opaque handle (client-sync §12.1, canonical body `{v, purpose, issued_at, expires_at, h}`): the `h` handle is unknown / revoked / expired / cross-bound, or its stored binding (principal, device, service, filter_digest, purpose) does not match the authenticated request. Distinct from cursor_expired (TTL) and cursor_unrecognized (cross-service portability miss). Client MUST clear local cursor cache and restart from initial /account/subscribe.
cursor_invalid code 400 endpoint The supplied cursor fails syntax, schema, purpose, binding, or integrity validation before the operation can advance state. Welcome recipient discovery also uses this code when its bound current eligibility revision changed or its frozen window is no longer retained; unrelated RealmCommit advancement alone does not invalidate it.
cursor_revoked code 410 endpoint Cursor integrity is valid but the issuing service has explicitly revoked this cursor authority before TTL expiry. Endpoint MUST NOT advance subscription position, barrier wait, or dropped recovery state; caller MUST restart from a fresh cursor. To-device queue deletion is decoupled from cursors and unaffected (client-sync.md §10.1).
cursor_unrecognized code 400 endpoint The cursor decoded successfully but cannot be used by this service because it is a stateful handle issued by another service. Caller MUST restart sync from a fresh cursor.
deactivation_federation_incomplete reason_code — account_status, federation_transaction, state_resolution Account deactivation could not be acknowledged by every peer Station inside deactivation_propagation_window_ms. Source services MUST keep deactivation fanout retrying and pause new Realm onboard, session/device grant, and KeyPackage publication for the principal.
decryption_failed reason_code — client_sync Recipient permanently cannot decrypt; epoch is unrecoverable on this device under current keys.
decryption_pending reason_code — client_sync Recipient cannot decrypt the targeted MLS epoch yet; client MUST surface a placeholder and continue retrying within the configured window.
delegation_revoked reason_code — auth_decision, service_call An applet/service call used a delegated device session that the deactivation/lock fanout revoked (ak.applet.registration delegated devices). The call MUST fail closed. See zh/identity/account-lifecycle.md §7.1.
delivery_target_unreachable reason_code — event_envelope, service_call Sub-reason carried by the ak.invite.revoke that moves a pending Invite to target_state=send_failed: the delivery service could not reach the private invite delivery target after its retry budget. It is a delivery diagnostic only and MUST NOT leak the 3PID plaintext, the invite token or a verification code. See zh/models/governance-objects.md section 5 and zh/sync/third-party-invites.md section 6.1.
dependency_missing code 409 both One or more exact Event, RealmCommit, predecessor, proof, or other signed dependencies are absent. The response MUST identify the bounded missing set in the operation's closed details/item shape. This is recoverable only through bounded canonical backfill/resolve followed by a new evaluation; it is not authorization denial or service unavailability. Dual-registered with the per-item/federation-transaction reason code.
device_already_authorized code 409 endpoint The device is already authorized.
device_authorized_principal_control_realm_mismatch reason_code — auth_decision, state_resolution A non-bootstrap ak.device.authorize event was submitted outside the principal's bound principal_control Realm, or the Realm purpose/profile/created_by does not match the device owner and issuer principal. Reducer MUST fail closed. See zh/identity/key-management.md §4.1.
device_directory_unavailable reason_code — service_call The requester's own Station could not obtain or verify a current attested device projection for an exact (account_id, device_id) on this call. It reports only the fetching Station's result, never target state, and MUST NOT be rendered as an omitted row or an empty device list. See zh/crypto-media/device-lifecycle.md section 8.2.1.
device_generation_fenced code 409 both The receiver knows an authenticated device-generation revocation or the security command fails the current generation revision check. New affected live submissions are fenced; ordinary historical eligibility is recomputed from the signed authority context and authenticated closures, not the receiver arrival time.
device_message_id_conflict reason_code — event_envelope, client_sync A to-device retry reused the same device_message_id with different canonical target content. The queue service MUST return duplicate_conflict with this reason_code and MUST NOT enqueue a replacement message. Scheduled-send plan convergence is keyed independently by scheduled_send_id and account-data CAS; durable ak.message.create identity conflicts are keyed only by the content-bound Event.event_id.
device_reanchor_authority_mismatch code 409 both A device re-anchor receipt scope, recovery session or transaction snapshot selects an account-local lineage or device generation that does not exactly match the covered ak.device.reanchor payload.
device_reanchor_authorize_mismatch code 409 both A device re-anchor completion authorization does not match the expected re-anchor authorization. Dual-registered as a service code and a reason_code (see reason_codes[]).
device_reanchor_checkpoint_mismatch code 409 both A device re-anchor completion carries a checkpoint that does not match the recomputed device checkpoint. Dual-registered as a service code and a reason_code (see reason_codes[]).
device_reanchor_conflict code 409 both Concurrent device re-anchor completions conflict on the same principal generation state.
device_recovery_generation_mismatch code 409 endpoint Device recovery proof or authorization references a device generation that does not equal the principal's current accepted device generation.
device_result_unavailable reason_code — service_call Single non-enumerating device directory failure. Absent, invisible, unrelated, revoked, fenced and policy-denied targets MUST all use this one value so a caller cannot probe device existence or revocation state. See zh/crypto-media/device-lifecycle.md section 8.2.
device_revocation_pending code 409 endpoint The exact device generation is blocked by one or more durable accepted ak.device.revoke proposals that have not been terminally rejected by a confirmed RealmCommit command result or covered by an accepted RealmCommit. Timeout and cache eviction do not clear this state.
device_revoked code 409 endpoint The device has been revoked.
device_unauthorized code 403 endpoint The device is not authorized for the requested operation. This is the typed local/self-surface outcome when no complete current accepted device authorization can be derived; anti-enumerating peer device-revocation checks instead return a signed authority_mismatch decision. A malformed row that claims current verified authorization while omitting its required Event/generation binding is an internal projection-integrity failure, not this ordinary authorization outcome.
device_unknown code 404 endpoint The referenced device id is unknown, not visible, or no longer active for the target principal.
did_already_exists code 409 endpoint A DID operation attempted to create or register a DID that already exists under the registry's uniqueness rules.
did_method_successor_invalid code 409 both The proposed current resolution is not a valid method-native same-core successor. A valid PCR author proof alone cannot advance it.
did_not_found code 404 endpoint The requested DID cannot be found under the active identity registry and anti-enumeration policy.
did_proof_required code 401 both An explicitly selected DID-root authentication factor or sensitive account-control transition requires its operation-specific fresh DID proof. Soft logout does not use this code as a refresh challenge: it requires full reauthentication to a fresh AccountHandoff or an explicit account-control action.
did_revoked code 410 endpoint The requested DID exists in historical registry state but has been deactivated, revoked, or superseded.
did_unknown code 422 both A DID cannot be resolved or validated under the active resolver policy.
digest_mismatch code 422 both A declared digest does not match the transferred content.
direct_conversation_binding_invalid reason_code — event_envelope, auth_decision, state_resolution The ak.self.events.command.submit.v1 Direct Conversation binding-integrity stage rejected an ak.direct_conversation.bound Event because its issuer, pair key, authorization basis, Realm role, exact two-member set, main Strand, founding unit digest, or founding MLS references did not match accepted authoritative facts. The rejection occurs before result application, is atomic, and writes nothing; see contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_founding_unit_invalid reason_code — event_envelope, service_call, federation_transaction A Direct Conversation founding unit is not the closed caller-authored four-Event unit. Causes include a count other than four, wrong wire order, a missing peer or founder ak.member.state{join}, a missing ak.strand.create, a fifth Event, a mixed actor/pair/profile/Realm, any envelope field naming a predecessor Event inside the unit, an envelope realm_id that is not retype(events[0] event_id), a main_strand_id that is not retype(events[3] event_id), a founding_unit_digest that does not match the recomputed value, or any request field asserting a service-allocated identifier, reservation handle or materialization draft, or a genesis whose initial_join_rule, initial_discoverability or initial_history_access is not the create-locked closed, invite_only or since_join. Carried under failed_precondition on both the self and the peer path; the whole unit is rejected with zero writes. See zh/identity/contact-and-direct-conversation.md sections 5.5 and 6.1.
direct_conversation_invite_forbidden reason_code — event_envelope, auth_decision The ak.self.events.command.submit.v1 active-profile invite guard rejected an ak.invite.create or ak.invite.third_party Event targeting a Direct Conversation. A pair-external candidate is classified earlier as direct_conversation_third_party_member_forbidden; the atomic founding peer join is not an invite. The rejection writes nothing; see contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_member_count_invalid reason_code — event_envelope, auth_decision, state_resolution The ak.self.events.command.submit.v1 exact-two profile gate rejected a new write because the Direct Conversation binding or authoritative membership projection did not resolve to exactly two distinct principal participants. Existing stable conversations are returned read-only by ak.self.direct_conversation.read.resolve.v1 as suspended with blocker member_count_invalid, never as a write rejection. The rejection writes nothing; see contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_pair_materialization_conflict reason_code — event_envelope, auth_decision, state_resolution A second accepted Direct Conversation Realm was observed for the same pair_key while both carried apparently valid founder admission, four exact Events, four consecutive source RealmCommits and founding-authority evidence, indicating slot, cutover-fence or signature equivocation by a trusted current Station. Both Realms freeze new Message, membership, policy, MLS and binding writes and all evidence is retained; implementations MUST NOT pick a winner by Realm-token lexical order or arrival order, tombstone either Realm, or migrate history. See zh/identity/contact-and-direct-conversation.md §5.7.
direct_conversation_participant_authority_denied reason_code — event_envelope, auth_decision, service_call The current governance Station's active ak.authority.direct_conversation_participant.v1 evaluator rejected an Event-mapped allowlisted action because it could not establish every required immutable binding, exact participant, active membership, Realm/Strand/current scope-derived MLS group-and-epoch cross-binding, lifecycle, resource, directional Contact, device, or Agent input. The ak.self.events.command.submit.v1 rejection exposes only this non-enumerating reason and writes nothing. Encrypted Signal product actions use their own outer admission carrier and recipient policy, never this Event reason. Consent, created_by, a local projection row, Realm owner aggregation, or an arbitrary Event/current result cannot substitute; see contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_root_mask_violation reason_code — event_envelope, auth_decision The ak.self.events.command.submit.v1 technical-root phase-mask stage rejected an operational, grant, member-governance, policy, or terminal action outside the exact active Direct Conversation founding/materialization mask. Root owner aggregation cannot bypass participant authority or target the other participant. The rejection writes nothing; see contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_slot_already_committed reason_code — service_call, federation_transaction The founder's current Station already closed its local (founder_id, trust_domain_id, pair_key) founding slot with a different unit, so this unit is refused with zero writes. Carried under conflict. The caller MUST re-resolve the existing coordinates through ak.self.direct_conversation.read.resolve.v1 instead of authoring another unit; the service MUST NOT accept a second unit, degrade it to a partial acceptance or quarantine it. A byte-identical replay of the committed unit is not this code: it returns the same four byte-identical source RealmCommits without changing the fourth committed_at. See zh/identity/contact-and-direct-conversation.md section 5.5.
direct_conversation_space_forbidden reason_code — event_envelope, auth_decision A Space create/update/parent/archive/restore/tombstone operation targeted a Realm carrying ak.profile.direct_conversation_realm.v1. Space containers are not permitted in this constrained Realm role.
direct_conversation_terminal_forbidden reason_code — event_envelope, auth_decision, state_resolution The ak.self.events.command.submit.v1 profile terminal guard rejected ak.realm.destroy or ak.realm.tombstone against the canonical Direct Conversation Realm. DM coordinates are permanent and successor-free. Reversible archive/freeze and their reverse transitions remain subject to ordinary authority and do not match this reason. The rejection writes nothing; see zh/identity/contact-and-direct-conversation.md §8.1 and contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_third_party_member_forbidden reason_code — event_envelope, auth_decision The ak.self.events.command.submit.v1 candidate-pair membership stage rejected an invite or join whose candidate ActorId was not one of the immutable Direct Conversation binding's two exact ActorIds. This reason has precedence over direct_conversation_invite_forbidden when both predicates match. Group expansion requires a new ordinary Collaboration Realm. The rejection writes nothing; see contract-registry.json operation_registry.direct_conversation_admission_mappings.
direct_conversation_unavailable code 409 both Opaque failed_precondition sub-reason for direct-conversation resolution when the peer, either directional Contact head/scope, trust-domain binding, or no-create binding state cannot be disclosed. Consent is not queried. Requester-visible status, body and timing MUST NOT distinguish those causes; detail is holder-private audit only.
direct_download_disallowed_presign_forbidden reason_code — authz, service_call A presigned blob URL was requested for a Realm-owned blob whose current effective asset policy does not explicitly set direct_download_allowed=true. Missing, unverifiable, non-effective, omitted, or false policy state all fail closed. The service MUST deny presign and require authenticated fetch or an authorized proxy path.
discovery_failed code 404 endpoint Discovery of the requested resource failed.
discussion_track_disabled code 409 both The target Strand discussion track is disabled.
duplicate_clause_claim code 422 both An SDK conformance claim repeats the same stable clause_id; each applicable clause must appear exactly once.
duplicate_conflict code 409 both The same idempotency key, non-Event stable identifier or Event identity was reused with different canonical content or canonical Event bytes. An Event Envelope whose carried event_id does not match its own digest uses event_id_digest_mismatch; confirmed full-hash collision evidence uses witness_disagreement.
e2ee_key_source_unauthorised reason_code — service_call A backend media SDK supplied an SFrame / frame encryption key from a source other than the Arkret MLS exporter (label `ak.rtc-frame-key/v1`). Clients MUST reject and refuse to publish / subscribe media. Closes the attack where backend cloud key escrow could intercept ostensibly-E2EE media. See zh/crypto-media/media-service-binding.md §8.1.
e2ee_required code 403 service_call Realm or call policy requires E2EE and the requested media path did not satisfy it.
effective_scope_reducer_managed reason_code — schema_validation Sub-reason for schema_violation when an actor-supplied payload illegally carries `effective_scope` where the object schema reserves that name for a read-only materialized projection. Both surfaces are decided by schema: the create shape bans the member (event-payload.schema.json#/$defs/relation_create_object), and the update shape bans the `effective_scope` / `effective_scope.*` patch paths (#/$defs/relation_update_payload), registered in registry/reducer-managed-path-registry.json. The Event envelope instead requires producer-signed `scope_ref`; the receiver derives the scope from payload and frozen pre-state, verifies exact equality, and only then may copy it into the object's effective_scope projection. See zh/models/circle.md §6.2.
egress_policy_denied reason_code — authz, federation_transaction, service_call An outbound Applet, MIMI, or federation transfer would emit plaintext or derived content without the egress grant, data-class allowance, or destination policy required for that transfer. It also covers SSRF address-class denial: a server-side fetch whose resolved target (after redirect / Alt-Svc) hits a forbidden address class such as cloud metadata, internal, or loopback is rejected with this reason, for example MIMI proxy_download. The sender MUST reject the transfer before releasing content. See zh/sync/api-conventions.md §11.2 and zh/extensions/mimi-interop.md §11.
enclave_no_upstream_proxy_for_external code 403 endpoint No upstream proxy is configured for external egress from the enclave.
enclave_not_trusted code 403 endpoint The enclave is not trusted for the requested operation.
epoch_mismatch code 409 both An encrypted authoring request references an epoch, group_state_ref or key_access_revision that differs from the ready current MLS group. HTTP 409. After verifying and acquiring current local MLS state, the sender re-encrypts into a new request; an exact retry of the old request does not re-encrypt. If the current scope itself awaits a winning Commit, failed_precondition with epoch_update_required takes precedence. Historical accepted Event replay and peer committed replication use their accepted historical binding.
epoch_update_required reason_code — crypto, service_call, state_resolution A membership change on the scope's own stream advanced key_access_revision and the current MLS epoch does not yet have a winning ak.mls.commit whose governance_binding covers that revision. Clients MUST pause new application messages for the scope until the effective epoch catches up. Endpoint authorization and policy changes never produce this reason. See zh/crypto-media/encryption-and-audit.md §2.4.1.
erasure_pending_is_terminal reason_code — account_status, event_envelope, state_resolution An Account Authority issuer-ledger mutation attempted to create a successor after `erasure_pending`. The state is terminal because erasure physically destroys data; the current-head transaction and every receiver MUST reject the successor and retain the terminal record. See zh/identity/account-lifecycle.md §3.
erasure_receipt_authority_invalid reason_code — account_status, identity_resolution, service_call The erasure receipt issuer, signing verification method, service transport identity or accepted-at authority chain does not establish authority for the claimed erasure scope. The receiver MUST reject before deletion or durable acknowledgement.
erasure_receipt_proof_invalid reason_code — account_status, identity_resolution, service_call One or more required erasure receipt proofs fail canonical transcript, signature, threshold or validity-window verification. The receiver MUST reject before deletion or durable acknowledgement.
erasure_receipt_stub_binding_mismatch reason_code — account_status, identity_resolution, service_call The retained stub carried with an erasure receipt does not bind the receipt scope, subject, terminal status or required verification coordinates. The receiver MUST reject before deletion or durable acknowledgement.
erasure_receipt_stub_digest_mismatch reason_code — account_status, identity_resolution Retained erasure stub bytes do not match retained_stub_digest in the erasure receipt. Verifier MUST reject the receipt and treat the erasure as not completed (fail closed).
erasure_request_already_pending reason_code — account_status Sub-reason for failed_precondition on ak.gate.account.command.request_erasure.v1: the account already holds a live self-initiated erasure intent whose erasure_pending AccountStatusRecord has not yet been signed. The client MUST NOT submit a second distinct request; it either awaits the recorded intent or withdraws it inside the deployment-granted withdrawal window. Once the record is signed, requests fail at authentication with account_erased instead. See zh/identity/account-lifecycle.md section 8.1.
event_id_digest_mismatch reason_code — event_envelope Sub-reason for schema_violation when the carried event_id does not equal the value re-derived from the Event's own canonical content per zh/conformance/encoding.md section 4.0. Receivers MUST re-derive and compare before using event_id for deduplication, indexing, routing, idempotency or authorization, and MUST NOT report this as proof_invalid: the distinct code is what localises cross-implementation canonical-JSON divergence and what prevents a forged event_id from entering the duplicate_conflict quarantine path.
evidence_recipient_mismatch reason_code — moderation_decision, moderation_report A moderation evidence package's encrypted_to recipient does not match the declared recipient_public_key_ref binding. The submission MUST reject. See governance/content-moderation.md.
expired_invite_token reason_code — state_resolution Invite token's expires_at has passed when claim is attempted. Internal-only reason code; the wire response MUST be the unified non-enumerable `not_found` per zh/sync/third-party-invites.md §6.1.
external_invite_actor_mismatch code 403 endpoint The external invite actor does not match the authenticated actor.
external_rate_limited reason_code — service_call Bridge / applet transaction failed because the external upstream service rate-limited the request, distinct from the local `rate_limited` (this service's own limit). Carried as a bridge_error error_code with error_class=rate_limit; the caller MAY retry after retry_after_ms. See zh/extensions/applet-schema.md §7.
external_user_no_main_access code 403 endpoint The external user has no access to the main deployment surface.
failed_plane code 412 both authority-commit plane invariant failed: the registered reducer projection for a Event targeted a data-plane typed current result, or a Event targeted a control-plane typed current result. Terminal failure state; the write MUST NOT be bypassed as cas_conflict. See zh/authz/event-auth-state-resolution.md §13 and zh/sync/service-http-binding.md (write outcomes).
failed_precondition code 409 both Reducer state-machine or typed CAS precondition failed. A stale typed revision writes nothing and does not carry a generic current/current_result Problem extension; authorized current is obtained only through a separately registered read. Other failures may carry a registered reason_code in the {strand,space,morph}_not_active / _not_archived or {strand,space,morph,message,relation}_already_terminal families, or an object-specific reason such as space_parent_cycle. See zh/models/common-fields.md §5.1 and zh/sync/current-results.md §2.
federation_actor_origin_denied code 403 service_call The federated actor origin was rejected by inbound policy.
federation_authority_mismatch reason_code — federation_transaction, service_call HTTP Message Signature @authority / target URI host does not match the resolved service endpoint for Destination-Service-ID, or the Destination-Service-ID is not authorized by Realm policy for the requested federation operation. Receiver MUST reject before processing events.
federation_interop_track_only code 501 service_call The requested federation surface is interop-track only.
federation_origin_denied code 403 service_call The federated origin was denied.
federation_private_read_rail_local_only code 501 service_call The private read rail is local-only and not federated.
federation_trust_domain_mismatch reason_code — federation_transaction, service_call Destination-Trust-Domain does not equal the receiver deployment's ServiceDescribe.trust_domain, or does not match the receiving Realm's trust_domain (zh/sync/federation.md §3.2). Internal audit-only reason; the wire response MUST be the unified minimal-disclosure authentication failure envelope.
first_backup_gate_unsatisfied code 409 endpoint The recovery-material gate requirements (first accepted RealmCommit and genesis recovery policy) are not satisfied.
focus_mismatch reason_code — service_call, auth_decision Media token exchange (ak.self.call.media.exchange.issue_token.v1) requested a `focus_id` different from the already-committed `ak.call.state.session_focus`. Token issuer MUST reject; clients MUST re-target the established focus rather than retrying with the original preference. See zh/crypto-media/media-service-binding.md §3 and §5.
focus_unavailable_for_client reason_code — service_call Client cannot use the committed `session_focus` (e.g. focus not in local `foci_preferred[]`, region restricted, capability mismatch). Client MAY fail closed without joining the call rather than silently degrading; clients MUST NOT pick a different focus to bypass `session_focus_no_split_brain`. See zh/crypto-media/media-service-binding.md §5.
founding_device_commitment_mismatch reason_code — pcr_genesis The FoundingDeviceDescriptor, authorize payload, device/HPKE digests, algorithms or root creation transcript are not byte-for-byte consistent.
franking_proof_unavailable code 503 both E2EE franking proof cannot be produced for the requested ciphertext (sender did not include franking sidecar). See zh/governance/content-moderation.md §3.4.
franking_tampered code 400 endpoint The franking tag is tampered or does not verify.
gate_check_failed reason_code — auth_decision, state_resolution External applicant-facing generic join gate failure. Wire response MUST NOT reveal whether a claim was absent, revoked, issuer-unreachable, parent-membership-missing, or challenge-invalid; detailed diagnostics are audit/reviewer-only. See zh/governance/join-policy.md §5.
governance_binding_mismatch reason_code — event_envelope, state_resolution, federation_transaction An MLS Commit's mls_governance_binding GroupContext extension does not match the accepted key-access state, Event payload or active epoch chain: scope/base/epoch fields disagree, the unsigned monotonic key_access_revision counter differs from the Station's accepted key-access revision, or extension bytes differ from the Event payload. The receiver MUST reject the Commit - and, on a federation push, the batch - rather than advance an epoch under a forged or stale binding. See zh/crypto-media/encryption-and-audit.md §2.5.
grant_already_consumed code 400 endpoint Session-grant rotation targeted a grant that was already single-use consumed (rotated). Treated as a credential-compromise signal; the rotation chain SHOULD be terminated. See account-lifecycle §4.1.
grant_exceeds_issuer_authority reason_code — event_envelope, auth_decision An `ak.capability.grant` attempts to grant actions[] / resources[] that exceed the union of its `issuer_authority_refs[]` at the issuing authority commit basis. Holding the `ak.capability.grant` action alone does not permit minting authority the issuer does not itself hold; reducers MUST fail closed (schema_violation for actions/resources over-scope, failed_precondition when the issuer does not hold the required upper bound at that basis). See zh/authz/capabilities.md §3.2.
grant_relinquish_not_subject reason_code — event_envelope, auth_decision A ak.capability.relinquish named a grant whose subject is not the actor. Relinquish is subject-only precisely so it needs no revoke capability; allowing any other actor would turn it into an unauthorized revocation. The authority-root typed current result is not a grant and can never be a relinquish target. The rejection MUST NOT disclose whether the target exists.
grant_revoke_not_authorized reason_code — event_envelope, auth_decision A ak.capability.revoke passed ordinary action authorization but failed the target guard: the actor is neither the target grant's issuer nor the current root controller of the target grant's own realm_id. Controlling some upstream root reachable through authority_root_refs is deliberately not enough — a co-owner or sibling MUST NOT be able to revoke an upstream or peer grant by holding ak.realm.owner. The rejection MUST NOT disclose whether the target exists or which Realm it belongs to.
grant_revoked_before_event_checkpoint reason_code — auth_decision The capability grant cited as authority was revoked at a checkpoint causally preceding this event; reducer rejects.
grant_revoked_upstream reason_code — auth_decision, state_resolution A child grant or Event depends on a parent grant that is locally known to be revoked, superseded, expired, or tombstoned. Reducers MUST fail closed immediately. See zh/authz/capabilities.md §10.3.
grant_validity_window_empty reason_code — auth_decision, event_envelope A capability grant's normalized effective validity window is empty: effective_not_before >= effective_expires_at after intersecting its temporal constraints. Reducer MUST reject the grant. See zh/authz/capabilities.md §6.1.
handle_holder_acceptance_missing reason_code — auth_decision, service_call A restricted HandleClaim status view was presented as status=verified while its immutable claim core omitted or invalidated the required holder_acceptance proof over the exact claim_digest (including claim.subject_account_id, claim.handle and claim.audience). Verifiers MUST reject the entire status view: it MUST NOT enter the verified candidate set, be displayed as verified, or drive grant conditions, roster strong attribution or AccountId targeting. This closes issuer-unilateral impersonation within the issuer's audience. See zh/identity/identity-handles.md §6.
handle_homograph_forbidden reason_code — schema_validation, service_call Handle registration collided with the same authority-local handle-namespace UTS #39 skeleton index or failed the authority's declared Highly Restrictive registration policy. This is registration policy, not canonical equality; the skeleton never enters wire or proof bytes. See zh/identity/identity-handles.md §17.
harassment reason_code — moderation_report Standard moderation reason: harassment.
hate_speech reason_code — moderation_report Standard moderation reason: hate speech / targeted attacks against a protected group.
historical_did_evidence_invalid code 422 both Registration-time or Event accepted-at DID evidence cannot be replayed at its frozen historical boundary. Current DID state MUST NOT be substituted.
historical_only code 200 endpoint Historical-only diagnostic for endpoints that explicitly register this outcome; it does not bypass current authentication and is not emitted by the closed peer event submit path after origin service-key revocation.
history_not_visible code 403 both The requested Event range, backfill window, or preview field is not visible to the caller under the target Event's T0 history_access and the current safety policy. Non-enumerating surfaces MAY map this to not_found. See zh/governance/history-visibility.md.
hlc_logical_overflow code 503 both The producer cannot allocate a fresh HLC logical counter in the current millisecond without violating monotonicity.
http_signature_invalid code 401 endpoint A per-delivery RFC 9421 HTTP Message Signature failed verification; the Content-Digest header profile, exact-content digest, or canonical-JSON wire check failed; or source_id disagreed with the Source-Service-ID header / signature transcript. Applies to Applet transaction push and to MIMI provider-to-provider writes (zh/extensions/mimi-interop.md §5). See zh/extensions/applet-integration.md §7.3.1.
http_signature_required code 401 endpoint A service-to-service request that MUST carry a per-delivery RFC 9421 HTTP Message Signature presented only Authorization: Bearer with no Signature. Applies to Applet transaction push in both directions (node->Applet and app/bridge->arkret edge inbound) and to MIMI provider-to-provider writes (zh/extensions/mimi-interop.md §5). See zh/extensions/applet-integration.md §7.3.1.
human_approval_required reason_code — auth_decision, service_call An agent runtime requested a high-risk session scope that requires out-of-band controller approval. The top-level service error is claim_required; error.details carries this reason_code and an opaque approval_request_id. The runtime MUST NOT receive a CAPTCHA, OTP, or browser challenge. See zh/identity/key-management.md §3.2.
ice_config_denied code 403 service_call Service refused to issue ICE configuration for this call or participant.
identity_creation_already_accepted reason_code — identity_creation, service_call The exact Principal Control Realm genesis for this provisional identity has already been accepted and MUST NOT be abandoned. The Account Authority checks the frozen identity creation operation and durable PCR submission/result evidence. An uncertain dispatch is not evidence of non-acceptance. Return the stable terminal result without creating an orphan anchor tombstone, suppressing the checkpoint or releasing the lease. Established identities use the account deletion / erasure path. See zh/identity/key-management.md §5.0.2.
identity_creation_challenge_already_consumed reason_code — identity_creation, service_call The identity-binding challenge was already consumed and the request is not a byte-identical replay whose canonical request digest matches the stored successful outcome. The Account Authority MUST reject it before any state transition; an exact replay returns the recorded outcome instead of this code.
identity_creation_challenge_expired reason_code — identity_creation, service_call The persisted identity-binding challenge expired before first successful consumption. The Account Authority MUST reject before publishing the DID operation or relaying PCR genesis, and the client must obtain a fresh challenge for the same frozen draft.
identity_creation_lease_fenced reason_code — identity_creation The identity-creation lease fence is no longer current. A stale holder cannot publish or complete the frozen account/principal registration.
identity_method_evidence_invalid reason_code — identity_resolution, auth_decision Submitted method_history_evidence fails independent verification: broken inception/current hash chain, SCID mismatch, invalid controller proof, unmet witness threshold, or stale evidence. An Applet-managed principal MUST carry a complete webvh_log; did:web snapshots, did:key expansion and service attestation are not substitutes. See zh/extensions/applet-integration.md.
illegal reason_code — moderation_report Standard moderation reason: content alleged to violate applicable law (CSAM, threats, IP infringement, etc.).
initial_session_request_mismatch reason_code — identity_creation The InitialSessionGrantRequest digest, device id, audience, scope ceiling, or RFC 7638 thumbprint does not match the frozen registration and handoff holder binding.
integrity_failed reason_code — event_envelope, service_call A recording or transcription artifact failed digest, encryption-context, or integrity verification.
internal_error code 500 endpoint An internal service error occurred.
invalid_ack_token reason_code — service_call A to-device message ack carried an ack token that does not correspond to a delivered to-device cursor (unknown, malformed, or already-superseded). Carried under param_invalid. See zh/sync/client-sync.md §10.1 and zh/sync/service-http-binding.md device_messages/ack.
invalid_canonical_json reason_code — encoding Bytes are not valid Arkret canonical JSON (sorted keys, integer-only numbers, escape rules per encoding.md §1).
invalid_cursor reason_code — client_sync, encoding Cursor payload fails the §8.2 / §8.3 cursor syntax or schema before integrity verification. HTTP endpoints surface this as top-level `param_invalid` with reason_code `invalid_cursor`. Expiry uses `cursor_expired`; handle lookup or cross-binding failures use `cursor_integrity_invalid`; cross-service portability misses use `cursor_unrecognized`.
invalid_encoding reason_code — encoding Generic encoding violation (HLC format, UUIDv7 format, base64url alphabet, etc.) not otherwise classified.
invalid_membership_transition reason_code — authz, state_resolution Realm or Circle membership admission rejects an illegal FSM edge with failed_precondition and zero writes; see models/common-fields.md section 4.5.
invalidated_by_rate_limit reason_code — auth_decision An out-of-band invite code attempt was invalidated because the per-code attempt rate limit was exceeded. See zh/conformance/conformance-vectors.md §3.11 (ak.vector.invite.oob_code_entropy.v1).
invite_already_terminal reason_code — event_envelope, auth_decision An Invite state transition is rejected because the target Invite is already in a terminal flow state (`accepted` / `rejected` / `revoked` / `revoked_by_capability_loss` / `revoked_by_inviter_left` / `expired` / `invalidated_by_rate_limit`). Note the Invite `state` is the invite flow axis (not the generic object lifecycle axis); see zh/models/governance-objects.md §5.3.
invite_directed_invitee_mismatch reason_code — event_envelope, state_resolution The invitee account carried by an ak.invite.accept / cancel / revoke payload and the invite_directed_invitee record stored for that InviteId are not both absent and not both present and byte-equal. It closes both directions of zh/models/governance-objects.md section 5.3: a third-party Invite cannot release another account's directed slot with a forged invitee, and a directed Invite cannot hold its slot forever by omitting the field.
invite_event_actor_mismatch reason_code — service_call Sub-reason for failed_precondition when ak.self.invites.command.dispatch.v1 resolves invite_event_id to an accepted Event whose signing actor is not the authenticated session actor. The request carries only the Event ID; the service MUST NOT co-sign or re-author the resolved Event; see zh/sync/invite-addressing.md §7.
invite_event_unaccepted reason_code — service_call Sub-reason for failed_precondition when ak.self.invites.command.dispatch.v1 supplies an invite_event_id that this Station cannot resolve to an accepted durable ak.invite.create Event. Private delivery only starts from that resolved accepted Event; see zh/sync/invite-addressing.md §7.
invite_kind_requires_revoke reason_code — event_envelope, auth_decision ak.invite.cancel targeted a token/3PID Invite without a stored direct invitee binding. Only ak.invite.revoke may terminate that Invite class.
invite_live_target_occupied reason_code — event_envelope, auth_decision Sub-reason for failed_precondition when ak.invite.create targets an account whose Realm live-target slot invite_live_target is already claimed by another live directed Invite. The Event is not accepted, enters no canonical history and derives no typed current result write; the closed error.details is InviteLiveTargetOccupiedProblem carrying the occupying invite_id and create_event_id. See zh/models/governance-objects.md section 5.3.
invite_oob_entropy_too_low reason_code — auth_decision An out-of-band invite code was rejected because its entropy is below the required floor. See zh/conformance/conformance-vectors.md §3.11 (ak.vector.invite.oob_code_entropy.v1).
join_policy_duplicate_gate_id reason_code — schema_validation, state_resolution Sub-reason for a schema_violation on ak.realm.join_policy where gates[] contains duplicate gate_id values. gate_id MUST be stable and unique within the policy so that audit refs in ak.member.state{gate_proofs[gate_id=…]} are unambiguous. Wire response uses code=schema_violation with reason_code=join_policy_duplicate_gate_id. See zh/governance/join-policy.md §3.1.
join_rule_policy_mismatch reason_code — event_envelope, auth_decision Realm `ak.realm.join_rule` and `ak.realm.policy_bundle` declare conflicting join modes (e.g., `restricted` with no gate configuration, or `knock_restricted` with all-auto gates degrading to `restricted`). See zh/governance/join-policy.md §2.
json_invalid code 400 both JSON body cannot be parsed.
key_backup_wire_schema_required reason_code — schema_validation Station device/key surface received a `ak.keys.backups.*` request body that does not validate as `ak.schema.key_backup.v1`. Wire backups MUST carry the dedicated key-backup envelope with `series_id` and `series_seq`; client-local secret-storage envelopes are not accepted on wire endpoints. See zh/crypto-media/device-lifecycle.md §11.
key_replay code 409 endpoint A key upload, claim, consume, or device-message operation reuses one-time key material or a claim nonce outside the allowed single-use window.
key_transparency_proof_missing code 422 both A profile requiring log-backed key transparency omitted its inclusion proof, consistency proof, log head, or required witness evidence.
key_unavailable code 409 both Required encrypted content key, MLS epoch, or authorized key share is not currently available.
keypackage_already_consumed code 409 endpoint An MLS KeyPackage claim/consume/revoke operation targeted a KeyPackage that has already been consumed by a Welcome.
keypackage_claim_rate_limited reason_code — service_call Internal server-side audit reason recorded when an MLS KeyPackage claim exceeds the per-(requester_id, target_principal_id) rate limit. The outward response MUST stay anti-enumeration (generic `claim_failed` or rate-limited envelope) and MUST NOT leak target existence; this reason is the canonical audit-log token only. See zh/conformance/scalability-constraints.md §6 and zh/identity/key-management.md.
keypackage_expired reason_code — keypackage_lifecycle A reusable last-resort KeyPackage was revoked because its expires_at deadline elapsed. It MUST NOT be returned by a later claim. This is a revocation reason, not a KeyPackage lifecycle state. See zh/crypto-media/encryption-and-audit.md §2.6.2.
keypackage_rotated reason_code — keypackage_lifecycle A reusable last-resort KeyPackage was revoked because its holder came online and rotated it to fresh init / encryption key material. This is a revocation reason, not a KeyPackage lifecycle state. See zh/crypto-media/encryption-and-audit.md §2.6.2.
keypackage_unknown code 404 endpoint The referenced MLS KeyPackage is unknown, expired, revoked, or not visible to the caller under the active claim policy.
keypackage_welcome_envelope_mismatch reason_code — event_envelope, auth_decision An MLS Welcome arrived with a `claim_envelope` whose canonical signing input does not match the Welcome's actual intended_realm_id / claim_id / requester_actor_id, or the envelope signature does not chain to the requester's PCR current accepted device signing key and authorization Event. See zh/crypto-media/encryption-and-audit.md §2.6.
last_resort_not_supported reason_code — service_call, feature_discovery A KeyPackage claim requested a last-resort fallback from a server that does not advertise `ak.feature.mls_last_resort_keypackage.v1`. The server MUST continue to fail closed on an empty single-use pool and MUST NOT return a `last_resort=true` package. See zh/crypto-media/encryption-and-audit.md §2.6.2.
last_resort_realm_affinity_violation reason_code — service_call, auth_decision An attempt to reuse a last-resort KeyPackage outside its `intended_realm_id` Realm-scoped last-resort pool. Servers MUST reject. See zh/crypto-media/encryption-and-audit.md §2.6.2.
last_resort_rotation_required reason_code — service_call, crypto A holder that joined groups via a last-resort KeyPackage came online but has not rotated the package and performed the required group self-updates. Those updates do not retroactively restore old Welcome confidentiality. See zh/crypto-media/encryption-and-audit.md §2.6.2.
legal_hold_active reason_code — auth_decision Requested operation targets a blob / object currently under legal hold. ak.self.blob.command.presign.v1 / ak.blob.delete / redaction-equivalent operations MUST be rejected with this code; legal hold takes precedence over capability and TTL. See zh/crypto-media/media-and-blob.md §5.4.4.1.
limit_exceeded code 413 both A semantic protocol limit was exceeded even though the request body itself may be well-formed, such as a bounded recurrence expansion that cannot be returned within the v1 maximum result count.
media_negotiation_failed code 409 service_call SDP / ICE media negotiation failed after the request passed authorization and schema validation. Clients MAY retry with a fresh offer or rejoin flow; services MUST NOT treat this as authorization success for any durable call-state transition.
media_negotiation_timeout reason_code — event_envelope, state_resolution Call connection or capture media negotiation exceeded the registered timeout.
media_permission_denied code 403 service_call Caller lacks permission to create, join, answer, or modify the media session.
media_plaintext_service_not_authorised reason_code — auth_decision An SFU / MCU attempted to negotiate plaintext-decrypting media role without a matching Realm policy plaintext_visible_services[] entry whose data_classes[] contains media_plaintext, OR without the active media key-access revision covering media_service_decrypts=true. Free-text purposes do not grant authority. MUST be rejected; the SFU may still act as opaque RTP relay. See zh/crypto-media/media-service-binding.md §8.2.
media_plaintext_warning_required reason_code — auth_decision A client attempted to join a call where media_service_decrypts=true without first displaying the required prominent plaintext-service warning and obtaining explicit second confirmation. The client MUST reject the join before releasing a token or media key. See zh/crypto-media/media-service-binding.md §8.2.
media_service_binding_uncovered reason_code — service_call, state_resolution A media token / focus join was presented but the current MLS epoch governance binding does not cover the `ak.realm.media_service` binding the token relies on (token issuer trust-root sealing is unverifiable). The verifier MUST fail closed instead of trusting an uncovered media binding. See zh/crypto-media/media-service-binding.md §2.1.
media_service_foci_required reason_code — service_call, schema_validation `ak.realm.media_service` is missing the required non-empty `foci[]` list. Services MUST reject payloads that do not declare explicit media foci and MUST NOT infer a focus from unrelated endpoint fields. See zh/crypto-media/media-service-binding.md §2.
media_source_unavailable reason_code — event_envelope, service_call The source media required for recording or transcription was unavailable.
member_identity_proof_invalid reason_code — event_envelope, state_resolution The MemberIdentity object carried by ak.member.identity.update failed proof validation: proof.payload_digest does not equal the sha256 of the proof-less MemberIdentity RFC 8785 JCS canonical bytes, the signature does not verify under proof.verification_method, or the method is not controlled by the disclosed subject_actor_id. The event MUST NOT be promoted to a verified display identity. See zh/sync/client-sync.md §8.1.
member_identity_replacement_digest_mismatch reason_code — event_envelope, state_resolution A ak.member.identity.update replaces[] entry references an event whose payload.identity_payload carrier digest does not equal the declared payload_digest, or references an event under a different (realm_id, member_id, segment). The replacement edge is invalid; receivers MUST NOT remove the referenced event from the effective set on its basis. See zh/sync/client-sync.md §8.1.
member_identity_state_mismatch reason_code — event_envelope, state_resolution The optional expected_state_digest optimistic-concurrency guard on ak.member.identity.update does not equal the digest of the current effective set for the same (realm_id, member_id, segment): sha256 over RFC 8785 JCS of the exact signed payload objects of the effective updates ordered by event_id ascending, [] when empty (zh/sync/current-results.md section 2). The Station MUST reject the Event with failed_precondition and zero writes instead of applying it as a valid replacement.
member_identity_unknown_segment reason_code — event_envelope, schema_validation A ak.member.identity.update declared a segment value outside the v1 core enum (member_identity). Receivers MUST reject unknown segment values until a schema / profile revision extends the enum. See zh/sync/client-sync.md §8.1.
membership_compensation_conflict code 409 endpoint A compensation delegation/action/executor/admission/join binding is wrong, already consumed, absent, or conflicts with the current membership provenance. The operation performs no write on conflict and never removes a newer join Event.
method_not_allowed code 405 endpoint The path exists but the HTTP method is not supported.
mimi_draft_unsupported reason_code — service_call, schema_validation Counterparty declared a MIMI Internet-Draft version not supported by this interop profile. Facade MUST reject instead of guessing a nearby draft shape. See zh/extensions/mimi-interop.md §4.1.
mimi_e2ee_boundary_unmarked code 400 endpoint The MIMI payload crosses the E2EE boundary without being marked.
mimi_governance_binding_mismatch reason_code — service_call, state_resolution A MIMI facade found a governance binding, but its authenticated GroupInfo/GroupContext group id, room-binding group id, group id derived from current accepted MlsGroupCurrent.effective_scope, fixed binding fields, provider DID or target Realm/Strand do not agree. Receiver MUST quarantine or reject with zero projection writes. See zh/extensions/mimi-interop.md §4.1.
mimi_governance_binding_missing reason_code — service_call, state_resolution A MIMI facade attempted to project room state, groupInfo, key material, or message data into a Arkret Realm without a verifiable Arkret MLS governance binding. Receiver MUST quarantine or reject fail-closed instead of accepting unauthenticated MIMI state as Realm authority. See zh/extensions/mimi-interop.md §4.
mimi_observer_write_forbidden reason_code — service_call, authz The current accepted MIMI room binding has local_provider_role=observer during ak.open.mimi.command.submit_message.v1. The registered observer_role_guard rejects the whole request before Event construction, persistence, receipt or fanout, with zero write effect. Producer path: contract-registry.json operation_registry admission_guards. See zh/extensions/mimi-interop.md §7.
mimi_payload_digest_mismatch code 400 endpoint The MIMI payload digest does not match.
mimi_payload_invalid code 400 endpoint The MIMI payload is invalid.
mimi_policy_revision_mismatch reason_code — service_call, state_resolution A MIMI room policy component does not match the accepted Arkret ak.realm.policy_bundle revision. Facade MUST reject the update until a fresh policy projection is available. See zh/extensions/mimi-interop.md §4.1.
mimi_provider_unreachable reason_code — service_call Required MIMI provider directory, key material, or groupInfo dependency is temporarily unreachable. Facade MAY retry with bounded backoff but MUST NOT accept fallback state without governance binding. See zh/extensions/mimi-interop.md §4.1.
mimi_reporter_resolution_required code 403 endpoint MIMI reporter resolution is required before this action.
mimi_room_binding_event_invalid code 400 endpoint The caller-authored room binding Event is missing, unexpected, semantically inconsistent, or does not exactly bind the authenticated MIMI room update. These pre-admission causes deliberately share one outward envelope; the precise reason is audit-only.
mimi_room_binding_migration_proof_invalid reason_code — state_resolution A structurally valid ak.mimi.room_binding Event carries migration fields on another transition, its committed Event/RealmCommit lineage is not the same-room adjacent accepted->migrating current source, its asserted topology conflicts with the selected outcome, or its target MLS group conflicts with current accepted authenticated public state. Authority Event admission MUST reject with zero durable effects; missing or unpaired fields fail schema_violation first. See zh/extensions/mimi-interop.md §4.2.
mimi_room_binding_status_transition_invalid reason_code — state_resolution A ak.mimi.room_binding Event declared a payload.status value that is not a legal transition from the binding's current status (including an illegal initial status or any write after the terminal revoked state). Reducer MUST reject; the room binding status lifecycle is defined in zh/extensions/mimi-interop.md §4.2.
mimi_room_state_incompatible reason_code — service_call, schema_validation Incoming MIMI room state uses lifecycle, membership, policy, or extension shape not supported by the declared Arkret MIMI interop profile. Facade MUST reject or require a newer profile. See zh/extensions/mimi-interop.md §4.1.
minimal_disclosure_violation reason_code — moderation_decision, moderation_report A moderation evidence package discloses material beyond the minimal-disclosure obligation (for example unrelated plaintext message bodies or MLS private state). The evidence submission MUST reject. See governance/content-moderation.md.
misinformation reason_code — moderation_report Standard moderation reason: misleading / false information posing harm.
mls_activation_irreversible reason_code — state_resolution Sub-reason for failed_precondition when an Event would deactivate, replace or re-run the accepted ak.mls.genesis of an already activated Realm, Circle or Sidecar scope. Activation is a one-way transition with no protocol path back to plaintext. See zh/models/realm-and-space.md section 2.3.
mls_activation_required reason_code — state_resolution Sub-reason for failed_precondition when a Strand / Message / Morph / Blob content or metadata write carries plaintext into a scope whose ak.mls.genesis is already accepted. An activated scope accepts only RFC 9420 application ciphertext. See zh/models/circle.md section 7.
mls_genesis_already_exists code 409 both An MLS genesis operation attempted to initialize a group whose genesis state is already durably accepted. Receivers MUST preserve the existing group state and reject the conflicting initialization.
mls_genesis_binding_proposal_mismatch code 409 endpoint The proposed_group_genesis_binding differs from the signed Genesis binding, from the winning concurrently accepted Genesis binding, or is supplied after an accepted Genesis already exists. The losing caller MUST discard the proposal-bound proof, re-query without a proposal against the winning immutable binding, and MUST NOT reuse the old query/cache entry.
mls_governance_anchor_unreachable code 409 endpoint The exact canonical proof_target_basis does not dominate the exact caller-supplied, locally trusted canonical proof_base_basis: at least one base leaf is neither retained as a target leaf nor an ancestor of a target leaf. Concurrent or otherwise unreachable cuts produce this error; byte-identical base and target antichains are a valid zero-transition query and MUST NOT produce it. Missing required RealmCommit/Event/witness material that prevents the service from deciding dominance is revision_unavailable instead. The service MUST NOT substitute a single head, common descendant, target, or untrusted base. The caller MAY retry only with another complete locally trusted basis or another authorized proof service.
mls_governance_binding_stale reason_code — state_resolution, auth_decision A decrypting media service join or token request found that the current MLS group has not yet covered its current key_access_revision (a membership change is still awaiting its winning ak.mls.commit). Media policy fields such as media_service_decrypts and plaintext_visible_services are authorized from the current accepted policy projection and never advance key_access_revision. Receivers MUST refuse to act until a Commit covers the current revision. See zh/crypto-media/media-service-binding.md §8.2 and zh/crypto-media/encryption-and-audit.md §2.4.1.
mls_keypackage_claim_request_expired code 409 endpoint The MLS KeyPackage claim request has expired.
moderation_control_split reason_code — policy_decision, state_resolution Committed moderation control evidence is internally inconsistent or cannot be verified; downstream decisions depending on it fail closed until a complete valid state is available.
moderation_state_conflict reason_code — auth_decision, state_resolution The referenced moderation state cannot be verified as a complete valid projection. Read, write, and distribute paths MUST fail closed. See zh/governance/content-moderation.md.
morph_already_terminal reason_code — event_envelope, auth_decision `ak.redaction` targeting a Morph is rejected because the target Morph is already in terminal state `redacted`.
morph_kind_immutable code 422 both A Morph update attempted to change an immutable morph_kind after creation.
morph_not_active reason_code — event_envelope, auth_decision `ak.morph.archive` / `ak.morph.update` rejected because the target Morph is not in `active` state.
morph_not_archived reason_code — event_envelope, auth_decision `ak.morph.restore` rejected because the target Morph is not in `archived` state.
morph_profile_widens_schema_ref code 422 both Morph profile attempted to widen or replace schema_ref in a way that violates create-locked morph type rules.
no_strand_track_message_grant reason_code — auth_decision No active capability grant authorises ak.message.create on the targeted Strand track for the actor.
not_found code 404 both The target does not exist or is not visible to the requester.
not_implemented code 501 both The operation is registered but this deployment has not implemented the endpoint or binding.
not_member code 403 both Actor is not a member of the target Realm or scoped membership set for this operation.
nsfw reason_code — moderation_report Standard moderation reason: not-safe-for-work / explicit adult content posted outside permitted contexts.
object_id_not_event_derived reason_code — event_envelope Sub-reason for schema_violation when a create Event carries an object identifier in its payload for an object kind whose id MUST be derived from the create Event's event_id. Create payloads MUST omit the id; the reducer materialises it by retyping the complete event-derived EventId token. See zh/models/common-fields.md.
ok reason_code — batch_item, auth_decision, policy_decision Sentinel value indicating an item or decision succeeded with no further reason.
one_time_keys_exhausted code 409 endpoint No suitable one-time key or KeyPackage remains available for the requested device, principal, cipher suite, or profile.
operation_selector_required code 400 both Every canonical Arkret HTTP or TUS request MUST carry exactly one Arkret-Operation selector naming the exact locally advertised operation_id before body parsing, including endpoint families with one candidate. A missing selector fails with operation_selector_required. Endpoint uniqueness, payload shape, SDK version, defaults, and fallback MUST NOT replace the selector. WebSocket open frames carry the operation_id required by their frame schema.
operator_rejected reason_code — device_recovery Recovery-session `rejection_reason_code` value: an operator / admin surface explicitly rejected the session. Closed value set defined in artifacts/schemas/recovery-session.schema.json; completion ownership is defined in zh/identity/security-transactions.md §2.
organization_registration_challenge_invalid code 400 endpoint The referenced organization registration challenge is unknown, expired, already consumed without an exact successful-replay ledger match, or its purpose / audience / origin / trust_domain / local_admin_subject / requested_scopes binding does not match the submitted request. On first success the registry atomically records (challenge_id, canonical_request_digest, outcome): a byte-identical retry returns that outcome, while the same challenge with a different digest fails here rather than authorising a second intent.
organization_registration_control_proof_invalid code 400 endpoint The method-native control proof fails verification, was produced under a different signing context, does not bind the submitted challenge / organization / version_id, or its signer is not in the organization DID's control relationship at the pinned version. Resolvability of the DID is never accepted in place of this proof.
organization_registration_quorum_not_met code 400 endpoint proof_kind=governance_quorum but fewer than quorum_threshold distinct valid governance signatures were supplied, or two signatures resolve to the same verification method. JSON Schema cannot compare the array length against the declared threshold, so the receiver enforces it and fails closed rather than accepting a partial quorum.
organization_registration_revoked code 409 endpoint The local organization binding generation is revoked, which is terminal. This also covers an older generation atomically terminated with reason organization_registration_superseded when a new current generation was opened. Refresh MUST NOT revive it, and a receipt from it MUST NOT authorize after the current-generation pointer advances: a binding withdrawn locally, superseded by changed admin/scopes, or forced to revoked because the external DID was deactivated can only be replaced by a fresh registration with a new challenge and proof.
organization_registration_stale code 409 endpoint The organization binding is stale — the pinned version no longer reflects current control after a controller rotation, or the receipt has passed expires_at — and the attempted operation is on a high-risk path. Low-risk reads may still proceed; high-risk paths MUST fail closed until a successful refresh, so that one first-time proof cannot authorise the relationship indefinitely.
other reason_code — moderation_report Standard moderation reason: catch-all for reports that do not fit the named categories. MUST be accompanied by a free-text `description` field. See zh/governance/content-moderation.md §3.2.
overbroad_request code 422 service_call A presentation request asks for unrelated handles, credential identifiers, or global identifiers beyond its declared purpose.
pairing_expired reason_code — auth_decision, event_envelope Agent bootstrap pairing window elapsed before the first runtime key authorization completed. Generic list/get views close the open handle and report readiness not_ready with runtime_key_missing; only the pairing poll may return its operation-local runtime_state=pairing_expired diagnostic. Pairing expiry does not create, revoke or rewrite Realm grants. It never applies to previously keyed Agents: an expired replacement handle only clears open fields and pairing_open readiness.
pairing_request_expired reason_code — auth_decision, service_call A `ak.gate.account.command.pair_agent_key.v1` pairing request was presented after its `pairing_expires_at` (or the runtime key-pairing session id has been closed). The endpoint MUST fail closed; the controller MUST initiate a fresh pairing strand. See zh/identity/key-management.md §3.6.2.
param_invalid code 400 both A parameter value is syntactically or semantically invalid.
param_missing code 400 both A required parameter is missing.
partial_auth_state reason_code — state_resolution Authorization state for the event could not be fully resolved from the material the evaluator holds: a required grant, delegation link or current revocation status was not retrievable. It is an incomplete-evaluation diagnostic, never an admission outcome. The evaluator MUST NOT derive an allow cache entry from it and MUST either retry the dependency fetch or fail closed; a resolvable dependency that is merely absent is dependency_missing. See zh/authz/capabilities.md §10.3.
participant_binding_invalid reason_code — event_envelope, service_call A `ak.call.state` participant's `participant_binding` failed one of: (a) issuer_kid resolution against current `ak.realm.media_service.service_id`; (b) field consistency with the participant entry (`realm_id` / `call_id` / `focus_id` / `actor_id` / `device_id` / `participant_id`); (c) `expires_at` freshness vs event `created_at`; (d) signature verification. Reducer MUST `failed_precondition`. See zh/crypto-media/call-state.md §4.1.
participant_id_unrecognised reason_code — service_call Backend (LiveKit / SFU / etc.) signalled `ParticipantConnected` with a `participant_id` that has no matching value in the accepted call roster effective authority-ordered keyed set (or matches a value whose `participant_binding` fails verification). Client MUST refuse to establish media streams for that participant — this closes the attack where a compromised backend tries to inject unauthorized participants into the conference. See zh/crypto-media/media-service-binding.md §7.
patch_atomic_conflict reason_code — event_envelope, state_resolution A single payload.patch contains parent/child writes, duplicate target paths, selector-affecting writes, or another multi-path combination that cannot be applied as one deterministic atomic Event. Reducer MUST reject the whole patch rather than partially applying paths. See zh/models/event-and-patch.md §4.3.1.
patch_path_invalid reason_code — event_envelope An `ak.schema.patch.v1` patch path violates the ABNF grammar in zh/models/event-and-patch.md §4.2.1 (malformed identifier, quoted identifier, selector or numeric-index form, path > 1024 bytes, or nesting > 16 segments). Parser MUST NOT attempt fallback recovery; reducer rejects with this reason.
patch_path_reducer_managed reason_code — event_envelope An `ak.schema.patch.v1` patch path addresses a field the generic update surface does not own. The normative per-object path set is registry/reducer-managed-path-registry.json (universal minimum set plus per-object-kind additions, minus the named View `state` exemption); the description here is not the criterion and MUST NOT be read as one. The forbidden path and every dotted descendant of it are rejected together. See zh/models/event-and-patch.md §4.2.5.
patch_unset_redactable_field reason_code — event_envelope An `ak.schema.patch.v1` `$op="unset"` addressed a redactable content-carrier slot. The normative path set is registry/redactable-field-registry.json (Message / Morph content pairs; Strand Description and synthesis content pairs) plus any Realm-schema field marked `redactable: true`; the description here is not the criterion. Absence of a content slot on the materialized object is reserved for `never authored` and `cleared by redaction`, so an ordinary update MUST NOT remove it. This is a slot-existence rule, not a capability boundary: `$op="set"` on the same path is ordinary authoring and MUST be accepted even when the new value carries an empty body, and no patch op can reproduce the whole-object, terminal, audit-committed effect of redaction. `metadata`, `encrypted_metadata`, `metadata.title`, `metadata.summary` and paths under `metadata.fields` are NOT covered and MUST accept `$op="unset"`. See zh/models/event-and-patch.md §4.2.4.
payload_digest_mismatch code 422 both Encrypted payload digest does not match the declared encrypted envelope content.
payload_too_large code 413 both The request or blob exceeds declared size limits.
pcr_authority_stale code 409 both The accepted PCR authority checkpoint, device generation, recovery-policy version or account-local-lineage binding is stale. DID freshness cannot repair this failure.
pcr_genesis_conflict reason_code — pcr_genesis The deterministic Principal Control Realm already has a different authoritative genesis unit. The receiver MUST perform zero writes and MUST NOT replace the accepted founding device.
pcr_genesis_unit_invalid reason_code — pcr_genesis The closed ordered pair is not exactly one root-signed ak.realm.create followed by one founding-device-signed ak.device.authorize, or atomic validation failed. No partial write is permitted.
peer_state_stale_unavailable code 503 service_call The peer's state is stale and temporarily unavailable.
permission_denied reason_code — event_envelope, service_call A recording or transcription backend could not obtain the required media permission.
pin_target_not_pinned reason_code — event_envelope, state_resolution Sub-reason for failed_precondition when ak.pin.reorder addresses a (pin_scope, target_ref) that has no causally earlier surviving ak.pin.add assertion to inherit note and the remaining entry fields from. Reducers MUST NOT synthesize a rank-only entry that would put the target back into the roster. See zh/models/pins.md section 4.
policy_combination_invalid code 422 both The submitted Realm policy combination (discoverability × join_rule × history_access) violates the Realm policy compatibility rules. Reducer keeps the prior accepted state.
policy_denied code 403 both A Realm, organization, account, holder-disclosure, agent, or deployment policy explicitly denied the requested operation after syntactic validation and authentication succeeded. Use a narrower code when a more specific registry entry applies.
policy_revision_gap reason_code — event_envelope, state_resolution A ak.realm.policy_bundle update skipped one or more monotonic policy_revision values. Reducer MUST reject instead of accepting a discontinuous realm_policy_bundle revision.
policy_revision_rollback code 409 service_call A reducer rejected a Realm policy update because policy_revision is older than the current accepted revision.
policy_revoked reason_code — event_envelope, state_resolution The Realm policy authorizing capture was revoked while the capture lifecycle was active.
policy_stale code 409 endpoint The request depends on policy state older than the freshness window required for this operation or risk tier.
policy_unavailable code 503 endpoint The policy service, Realm policy facet revision, or policy proof required for this operation is temporarily unavailable.
policy_violation code 403 both A realm-level policy refuses the requested write or fanout (read-receipts §2.5: ak.receipt.read drops when disclosure='disabled'; retry_after_ms is null because retry will not change the outcome).
presign_expired reason_code — service_call, auth_decision A ak.self.blob.command.presign.v1 bearer URL was presented outside its nbf / exp window or after its nonce was revoked. Wire response remains non-enumerating not_found where required; audit logs may record this reason. See zh/crypto-media/media-and-blob.md §5.4.
presign_invalid reason_code — service_call, auth_decision A ak.self.blob.command.presign.v1 bearer envelope is syntactically invalid, has an unrecognised scheme, fails signature verification, mixes with Authorization header auth, or otherwise cannot be validated. Wire response remains non-enumerating not_found where required; audit logs may record this reason. See zh/crypto-media/media-and-blob.md §5.4.
presign_scope_mismatch reason_code — service_call, auth_decision A ak.self.blob.command.presign.v1 envelope scope does not match the requested blob_ref, method, byte range, purpose, Realm, issuer trust state, or current blob visibility. Wire response remains non-enumerating not_found where required; audit logs may record this reason. See zh/crypto-media/media-and-blob.md §5.4.
preview_policy_denied code 403 service_call A directory/resolve/search/projection request attempted to obtain a stripped preview, history stub, history snippet, or token-scoped preview that is not allowed by the effective ak.realm.preview_policy. External responses that must be non-enumerating MAY map this to not_found. See zh/governance/history-visibility.md §4.
primary_track_required reason_code — event_envelope, state_resolution An ak.strand.tracks.update patch attempted to disable or remove the current primary track without atomically transferring primary status to another active track. Carried under failed_precondition; the patch is rejected atomically. See zh/models/strand-and-message.md section 4.7.
principal_control_event_kind_forbidden reason_code — event_envelope, auth_decision A Realm claiming ak.profile.principal_control_realm.v1 received a collaboration / media / content event kind outside its allowlist-only control-plane event policy. Reducers MUST reject instead of treating the Realm as ordinary collaboration history. See zh/models/realm-and-space.md §2.8.1 and artifacts/profiles/conformance-profiles.json#profile_requirements.
principal_deactivated reason_code — auth_decision, event_envelope, service_call, state_resolution The account status checkpoint contains a deactivation for the exact AccountId acting as actor, subject, issuer, recipient, or device owner. New device/session grants, KeyPackage operations, capability delegation, membership writes targeting that account, push routes, and to-device enqueue MUST fail closed. See zh/identity/account-lifecycle.md §7.1 and the federation propagation rules of zh/identity/account-lifecycle.md §7.
principal_unknown code 404 endpoint The referenced principal DID or account principal is unknown or not visible to the caller.
private_attachment reason_code — service_call, auth_decision The target blob is actor_private / private attachment material and MUST NOT be exposed through a bearer presign URL. It remains fetchable only through header-authenticated actor-bound access. See zh/crypto-media/media-and-blob.md §5.4.4.1.
private_view_requires_account_data reason_code — event_envelope, schema_validation A shared Realm View Event attempted to persist visibility=private. Private Views are encrypted holder account data under ak.views.private.<view_id> and MUST NOT enter the shared reducer. Carried under schema_violation. See zh/models/views.md.
profile_unavailable reason_code — service_call Per-actor outcome of ak.self.actor_profile.read.resolve.v1. Unknown actor, actor without an accepted global profile, actor that is not an effective joined member of the request realm_id, and a caller not authorized for that actor MUST all report this single value, so the only outward carrier for PCR-resident ak.profile.create / ak.profile.update cannot be used to probe membership or account existence. See zh/discovery/profiles-presence.md §2.3.
projection_incomplete code 409 endpoint The requested projection cannot be claimed complete under the current supported feature set or dependency checkpoint.
proof_binding_missing reason_code — event_envelope, auth_decision Proof lacks a required `domain` or `audience` binding on a cross-service, cross-trust-domain, federation, or multi-audience call. Receivers MUST fail closed rather than accept a single-audience proof across services. A profile MAY define a more specific reason. See zh/models/event-and-patch.md §3.
proof_failed reason_code — device_recovery Recovery-session `rejection_reason_code` value: proof verification failures reached the server-side policy limit, so the session transitioned to `rejected`. Closed value set defined in artifacts/schemas/recovery-session.schema.json; completion ownership is defined in zh/identity/security-transactions.md §2.
proof_invalid reason_code — auth_decision, service_call A runtime key-pairing or session-grant proof (DID `assertionMethod` signature, agent_key_proof transcript, etc.) failed signature verification, transcript binding, or `proof_kind` check. Distinct from `signature_invalid` in that the wire shape was syntactically valid but the proof semantics did not bind to the expected principal / nonce / audience. See zh/identity/key-management.md §3.6.2.
push_gateway_unreachable code 503 endpoint The push gateway or downstream push provider could not be reached or is unavailable for this route. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
push_payload_too_large code 413 endpoint The notification payload exceeds the push profile, provider, or deployment size limit. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
push_route_limit_exceeded reason_code — event_envelope, service_call A `ak.device.push_route` registration would exceed the v1 wire limit of 16 active push_route entries per `(recipient_id, principal_id, device_id)`. The server MUST reject the new registration. See zh/crypto-media/device-lifecycle.md §5.6.2 and zh/conformance/scalability-constraints.md §6.1.
push_route_registration_rate_limited reason_code — service_call Internal audit reason recorded when push-route registration / rotation writes for a `(recipient_id, principal_id, device_id)` exceed the default rate (8 writes per 60s). The outward response uses a generic rate-limited envelope; this reason is for server-side abuse detection only. See zh/crypto-media/device-lifecycle.md §5.6.2 and zh/conformance/scalability-constraints.md §6.1.
push_target_unknown code 404 endpoint The requested push target, device route, or notification subscription is unknown or no longer visible. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
push_token_invalid code 400 endpoint The supplied push token is malformed, fails provider validation, or is not bound to the authenticated principal/device. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
push_token_unknown code 404 endpoint The push token or registration id is unknown, revoked, expired, or already unregistered. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
quarantine code 409 both The submitted item or operation result was quarantined by moderation, abuse, fork, policy, or risk handling and is not accepted as ordinary visible state.
quarantined reason_code — state_resolution, federation_transaction Item was placed in quarantine pending operator decision (state_conflict_resolution); not finalized.
query_invalid code 400 both Query parameters cannot be parsed or violate endpoint rules.
queue_full reason_code — batch_item Per-event rejection reason in an Applet edge transaction response (rejected[].reason_code) when the receiving side's inbound processing queue is saturated (backpressure) -- the Applet for node-to-Applet pushes, the Arkret edge for Applet-to-node pushes. The push sender MAY re-deliver the rejected events later under the same idempotency identity. See zh/extensions/applet-integration.md §7.3.
quorum_unreachable reason_code — event_envelope, auth_decision A threshold-governed control proposal can no longer collect the required independent acknowledgements before its deadline. The receiver MUST fail closed with reason_code=quorum_unreachable rather than guessing authority.
quota_exceeded code 403 both Storage, bandwidth, or compute quota was exceeded.
rank_exhausted code 409 both No valid fractional rank exists between the requested bounds; a rebalance or different position is required.
rate_limited code 429 both The caller exceeded the current rate limit policy. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
reaction_scope_mismatch reason_code — state_resolution Sub-reason for failed_precondition when a ak.reaction.* target_ref resolves to an object outside the reaction event's stamped effective scope. Reactions MUST target an object within their own effective scope. See zh/models/strand-and-message.md §9.8.2.
reaction_target_unsupported reason_code — schema_validation, state_resolution Sub-reason for schema_violation when a ak.reaction.add / ak.reaction.remove target_ref points at an object kind that the deployment does not allow reactions on. v1 core only allows ak:message: targets; profiles MAY register additional target kinds. See zh/models/strand-and-message.md §9.8.2.
realm_alias_authority_mismatch reason_code — state_resolution, service_call An ak.realm.alias declaration carried an alias whose <domain> is not an authority domain of this Realm's trust_domain, so the RealmCommit signature from the governance Station is not evidence that the domain's alias issuer authorized the claim. Domain reducers and directories MUST fail closed instead of registering a foreign-domain alias. See zh/discovery/object-addressing.md §3.3.
realm_alias_homograph_forbidden reason_code — schema_validation, service_call Realm alias registration collided with the same authority-local realm-alias-namespace UTS #39 skeleton index or failed its declared Highly Restrictive registration policy. Skeletons do not define canonical equality; cross-namespace handle/realm-alias homographs are disambiguated by sigil and type context. See zh/discovery/object-addressing.md §3.3.
realm_alias_taken reason_code — state_resolution, service_call An ak.realm.alias declaration requested a canonical alias already held by a different Realm in the same issuing authority's realm-alias namespace. The alias registrar MUST reject the later claim rather than re-pointing the alias; releasing an alias requires the holding Realm to publish an ak.realm.alias tombstone first. Handle namespace occupancy is NOT a collision (the two namespaces are disjoint). See zh/discovery/object-addressing.md §3.3.
realm_already_exists reason_code — event_envelope, state_resolution A ak.realm.create event attempted to create a Realm id whose genesis typed current result is already set. Reducer MUST reject the duplicate create without rewriting create-locked fields.
realm_authority_controller_mismatch reason_code — event_envelope, state_resolution, auth_decision An Event presented ak:result:realm_authority_root:null as its authorization_ref but the typed current result's current controller_actor_id is not the authorizing ActorId, or the epoch / authority_generation bound at issuance no longer matches the typed current result in that basis. Includes replaying a staged genesis-batch root proof outside its atomic bootstrap unit. See zh/authz/capabilities.md section 3.2.
realm_authority_root_conflict reason_code — event_envelope, state_resolution The authority-root typed current result value was author-supplied or otherwise diverges from the registered value_projection: controller_actor_id not equal to the create envelope actor_id, a non-zero controller_epoch or authority_generation at genesis, or members beyond the closed three-field shape. Reducer MUST reject the whole unit. See zh/models/realm-and-space.md section 2.5.
realm_authority_root_missing reason_code — event_envelope, state_resolution, auth_decision The Realm has no registered realm_authority_root typed current result in the authorization basis, or an ak.realm.create bootstrap unit failed to materialize it. Reducer MUST reject the entire bootstrap unit atomically without leaving genesis, profile, policy, or membership facets, and MUST NOT fall back to membership or a realm_state.owner projection mirror. See zh/models/realm-and-space.md section 2.5.
realm_federation_policy_closed code 403 service_call The realm federation policy is closed.
realm_federation_policy_invalid code 403 service_call The realm federation policy is invalid.
realm_federation_policy_quarantine code 403 service_call The realm federation policy has quarantined the peer.
realm_federation_policy_restricted code 403 service_call The realm federation policy restricts this peer.
realm_frozen code 403 both The target Realm is reversibly frozen or archived and the attempted write is outside the closed exemption set in zh/models/realm-and-space.md §2.6.0. A tombstoned Realm rejects ordinary writes with active failed_precondition; realm_terminal_state remains a reserved reason.
realm_id_not_event_derived reason_code — event_envelope Sub-reason for schema_violation when ak.realm.create carries a forbidden envelope realm_id instead of the realm_genesis shape, when a Collaboration Realm does not retype the full 33-byte create Event token, when a Principal Control Realm does not match the 0x11 subject transcript, or when payload.object still carries an id field. See zh/models/realm-and-space.md section 2.5.
realm_link_invalid_transition reason_code — state_resolution An ak.realm.link status transition is absent from the canonical domain-transition contract, including any non-byte-identical attempt to leave terminal tombstoned state. The reducer MUST reject with top-level failed_precondition. See zh/models/realm-links.md §4.
realm_link_self_reference reason_code — schema_validation, state_resolution An ak.realm.link targets its own enclosing Realm. Self-links have no cross-boundary meaning and MUST be rejected with top-level schema_violation. General directed cycles remain valid. See zh/models/realm-links.md §2.
realm_organization_authorization_invalid reason_code — event_envelope, state_resolution A ak.realm.organization statement failed organization-side authorization: payload.authorization.proof did not verify against the organization DID control state, threshold governance quorum, or the verification_method, or issuer_role is not allowed for the relationship. This is the generic organization-consent failure used when no more specific realm_organization_* reason applies. Downstream implementations MUST emit this exact code rather than inventing a bare string.
realm_organization_delegation_missing reason_code — event_envelope, state_resolution A ak.realm.organization statement whose authorization.issuer_role is governance_service or account_authority omitted authorization.delegation_ref, or the referenced delegation does not resolve to a live organization DID delegation whose purpose covers ak.realm.organization and the requested relationship/control_scopes.
realm_organization_expired reason_code — event_envelope, state_resolution A ak.realm.organization statement is outside its validity window: the evaluation time is before payload.not_before, after payload.expires_at, or outside the referenced delegation's validity period. Schema validation passes; the reducer MUST reject the statement as expired or not-yet-valid.
realm_organization_realm_acceptance_missing reason_code — event_envelope, state_resolution A ak.realm.organization statement lacks the Realm-side acceptance layer: the writing principal does not hold ak.realm.admin and the event is not part of an allowed create-bootstrap initial-configuration batch. Realm-side acceptance is independent of the organization-side proof.
realm_organization_scope_missing reason_code — event_envelope, state_resolution A ak.realm.organization statement asserts a control_scope (or relationship) that the verified organization-side authorization or its delegation does not cover. The endorsement boundary in payload.control_scopes exceeds what the proof/delegation grants.
realm_state_snapshot_authority_unverified code 403 endpoint The snapshot issuer, witness quorum, or signing authority cannot be verified for the requested Realm and manifest time.
realm_state_snapshot_chunk_digest_mismatch code 400 endpoint A conformance snapshot chunk digest does not match the declared digest.
realm_state_snapshot_issuer_revoked reason_code — client_sync, realm_state_snapshot_verification Snapshot signer's authority (Realm owner / admin / trusted snapshot issuer / witness quorum membership) was revoked before the snapshot's origin admission/issuance gate, or the verifier cannot prove the frozen authority basis. Client MUST quarantine or reject the snapshot. A revoke accepted after a valid snapshot issuance does not retroactively invalidate that snapshot.
realm_state_snapshot_unavailable code 503 endpoint The requested snapshot head or snapshot artifact is not currently available from this service.
realm_terminal_state reason_code — state_resolution, auth_decision Reserved diagnostic for a terminal Realm. v1 tombstone admission rejects later ordinary writes with active failed_precondition without this reason; ak.realm.destroy production admission is unavailable. See zh/models/realm-and-space.md §2.6.
realm_unavailable reason_code — auth_decision, state_resolution The effective target Realm is tombstoned, destroyed, unreachable, or not writable by the actor; default Realm resolution MUST fail closed instead of following Realm links or falling back implicitly. See zh/models/space-hierarchy.md §4.
reauthentication_required code 401 endpoint A high-risk self-service action (for example ak.gate.account.command.request_erasure.v1) requires fresh high-risk action authentication — recent login, WebAuthn, recovery key or a deployment equivalent — and the presented session does not satisfy the deployment policy. The caller MUST re-authenticate and retry with new request material; the strength of the required proof is deployment governance. See zh/identity/account-lifecycle.md section 8.1 and section 10.
recipient_unavailable reason_code — service_call A to-device delivery targeted a deactivated principal whose pending queue was dropped by the deactivation fanout; further delivery MUST fail closed rather than enqueue. See zh/identity/account-lifecycle.md §7.1.
recording_artifact_pipeline_bypassed reason_code — service_call A backend (LiveKit Egress / Janus recording plugin / etc.) attempted to deliver a recording artifact outside the Arkret-side blob pipeline — e.g. an Egress destination pointing to LiveKit Cloud / S3 / GCS direct, instead of the Arkret media service authenticated upload endpoint. Clients MUST fail closed. See zh/crypto-media/call-state.md §5 and zh/crypto-media/media-service-binding.md §8.1.
recording_consent_required reason_code — service_call, event_envelope A capture attempted to enter or stay in recording/transcribing without the consent evidence its Realm requires. The reachable trigger is the per-participant consent acknowledgment profile of zh/crypto-media/call-state.md §5.2: a recorded party has no current device-signed acknowledgment, or membership, device or capture epoch changed and the acknowledgment was not re-acquired. This code is NOT how a producer-declared consent value is refused: `call_recording_start_payload.result.retention.consent_confirmed` is `const: true`, so any other value is `schema_violation` before the reducer runs, and the capture-kind start-event ref is stamped by the reducer because the payload MUST NOT carry it. Reducer MUST reject before either capture FSM or result typed current result is written.
recording_denied code 403 service_call Recording or transcription is denied by Realm policy or participant consent state.
recording_state_transition_invalid reason_code — event_envelope An `ak.call.state` event requested a `recording_transition` or `transcript_transition` not listed in the per-capture controlled state machine (e.g. transitioning out of terminal `ready` / `failed`, `stopped → failed`, or attempting to enter a capturing state without a new `ak.call.recording.start`). The reducer MUST `failed_precondition`. The same code covers both orthogonal capture dimensions. See zh/crypto-media/call-state.md §4.2.
recovery_authorization_device_mismatch code 409 endpoint The recovery authorization device does not match.
recovery_authorization_principal_mismatch code 409 endpoint The recovery authorization principal does not match.
recovery_authorization_session_mismatch code 409 endpoint The recovery authorization session does not match.
recovery_control_event_kind_mismatch code 409 endpoint The recovery control event kind does not match the expected kind.
recovery_control_event_not_found code 409 endpoint The referenced recovery control event was not found.
recovery_evidence_unbound reason_code — recovery_transaction Recovery evidence does not bind the current transaction, recovery session, principal, replacement device or prepared-plan digest.
recovery_list_update_device_mismatch code 409 endpoint The recovery list update device does not match.
recovery_list_update_principal_mismatch code 409 endpoint The recovery list update principal does not match.
recovery_policy_conflict code 409 endpoint The recovery policy conflicts with the current state.
recovery_policy_device_unauthorized code 409 endpoint The device is not authorized under the recovery policy.
recovery_policy_genesis_not_v1 reason_code — schema_validation, state_resolution A recovery policy publish is the first accepted policy for the principal but does not use `version=1`. Genesis recovery policies MUST start at version 1.
recovery_policy_id_mismatch code 409 endpoint The recovery policy id does not match.
recovery_policy_mismatch code 409 both A recovery session or proof does not satisfy the principal's declared recovery policy. Dual-registered as a service code and a reason_code (see reason_codes[]). See zh/identity/key-management.md §8.
recovery_policy_missing code 409 endpoint No recovery policy is registered for the principal.
recovery_policy_revoked code 409 endpoint The recovery policy has been revoked.
recovery_policy_supersedes_invalid reason_code — schema_validation, state_resolution A non-genesis recovery policy rotation omits `supersedes` or names a predecessor other than the currently accepted policy_id for the principal. Servers MUST reject with 409 Conflict.
recovery_policy_trust_domain_mismatch code 409 endpoint The recovery policy trust domain does not match.
recovery_policy_version_mismatch code 409 endpoint The recovery policy version does not match.
recovery_policy_version_not_monotonic reason_code — schema_validation, state_resolution A recovery policy publish or rotation uses a `version` that is not strictly greater than the currently accepted policy version for the principal. Servers MUST reject with 409 Conflict.
recovery_principal_isolation reason_code — authz, device_recovery A recovery policy or recovery session request targets an AccountId different from the exact account bound to the authenticated SessionGrant. Servers MUST compare both principal_id and station_id and reject without revealing the target account's recovery state.
recovery_proof_authority_invalid code 401 endpoint The recovery proof authority is invalid.
recovery_proof_kind_not_allowed code 409 endpoint The recovery proof kind is not allowed.
recovery_proof_kind_unimplemented code 501 endpoint The recovery proof kind is not implemented.
recovery_proof_kind_unknown reason_code — schema_validation, device_recovery A recovery policy, receipt, or proof names a proof kind outside the ak.schema.recovery_policy.v1 methods kind union. Producers MUST use one of did_root, recovery_unlock, device_quorum, or trusted_recovery_service.
recovery_receipt_completed_at_after_commit reason_code — recovery_transaction A RecoveryTerminalCommit carries a recovery_receipt whose completed_at is later than the Station's own linearized commit time for commit_recovery_unit. The receipt's completed_at is the replacement device's authoring time for "completed if every check passes", so it can never be later than the commit that would make it true. The Station MUST reject the whole submission with this deterministic reason and perform zero authoritative writes: no accepted step, no terminal result, no accepted Event, no committed RealmCommit, no generation advance, no activated device and no consumed recovery session. v1 defines no skew allowance, the Station MUST NOT sign a future-dated completion attestation and MUST NOT block waiting for the client clock. The rejected request was never accepted, so a corrected submission MUST use a new receipt; bytes already frozen as a step outcome still return duplicate_conflict. See zh/identity/security-transactions.md section 2.2.
recovery_receipt_conflict code 409 endpoint The recovery receipt conflicts with the current state.
recovery_required reason_code — device_recovery, state_resolution An existing account endpoint lacks the durable account MLS root, dependent snapshot/reference unit, or material claimed by its emitted marker. Ordinary feature APIs MUST stop and enter the existing recovery/pairing path; they MUST NOT mint a replacement root or tree. See zh/identity/key-management.md section 7.3.1.
recovery_session_challenge_mismatch reason_code — device_recovery, schema_validation A recovery proof echoes a challenge value that does not exactly match the server-issued challenge for the referenced recovery_session_id. Servers MUST reject the proof before completing device recovery. See artifacts/schemas/recovery-session.schema.json and zh/identity/security-transactions.md §2.
recovery_session_conflict code 409 endpoint The recovery session conflicts with the current state.
recovery_session_id_reused code 409 endpoint The recovery session id has already been used.
recovery_session_not_pending code 409 endpoint The recovery session is not in a pending state.
reducer_projection_failed reason_code — event_envelope, state_resolution The reducer projection required by the registered contract cannot be derived uniquely from `kind`, signed envelope fields, schema-validated payload, and frozen pre-state. Receiver MUST reject the entire Event; projected writes are reducer output and never producer-selected Event fields. See zh/models/event-and-patch.md §4.3.1.
refs_too_large reason_code — schema_validation, event_envelope Event Envelope refs[] exceeds the v1 maximum of 128 semantic refs. Receiver MUST reject with schema_violation. See zh/conformance/scalability-constraints.md.
relation_already_terminal reason_code — event_envelope, auth_decision `ak.relation.tombstone` / `ak.relation.update` / equivalent Relation write rejected because the target Relation is already in the terminal state `tombstone`. In particular, `ak.relation.update` targeting a tombstoned Relation MUST be rejected with this reason_code.
relation_kind_contains_derived reason_code — event_envelope, schema_validation Sub-reason for schema_violation when a direct ak.relation.create / update / delete targets a derived-projection contains shape (Space(board) -> Space(list) or Space(list) -> Strand). Truth sources are the space_parent and strand_position typed results written via ak.space.parent / ak.strand.move / ak.strand.reorder Events; only the non-derived object-composition contains form is directly writable. See zh/models/relation.md §3.2 and zh/models/realm-and-space.md §3.5-§3.6.
relation_kind_watches_derived reason_code — event_envelope, schema_validation Sub-reason for schema_violation when a direct ak.relation.create / update / delete targets relation_kind=watches. The watches Relation is a derived projection only: its truth source is the strand_watch typed current result written via the ak.strand.watch.set durable event, never a direct Relation write. See zh/models/relation.md §3.2 and zh/models/strand-and-message.md §8.
resolution_history_ancestor_unknown reason_code — service_call Sub-reason for param_invalid when ak.self.identity.read.resolution_audit.v1 receives an after_resolution_event_ref that is neither the genesis Event nor an accepted ak.identity.resolution.update in this account's current resolution lineage. The audit surface is already exact-current-holder authorized, so a stale or foreign cursor is reported as an invalid parameter rather than folded into the anti-enumeration outcome. See zh/identity/identity-did.md §4.2.
response_invalid code 400 service_call A downstream service response was syntactically valid transport data but did not satisfy the expected protocol contract, including directory/projection/service-call schema mismatch or missing required pagination/error fields.
revision_stale code 409 both The service's verified authority-stream head is behind the RealmCommit position required by the request.
revision_unavailable code 503 endpoint The service cannot currently produce the requested checkpoint because required authority commit, reducer, or witness state is unavailable.
revocation_freshness_unknown reason_code — auth_decision, federation_transaction, state_resolution Revocation / grant freshness cannot be established for a high-risk, cross-domain, or delegated action. Receiver MUST fail closed and return freshness diagnostics instead of treating missing revoke evidence as allow.
risk_policy reason_code — device_recovery Recovery-session `rejection_reason_code` value: a server-side risk policy rejected the session. Closed value set defined in artifacts/schemas/recovery-session.schema.json; completion ownership is defined in zh/identity/security-transactions.md §2.
routing_unlinkability_presign_forbidden reason_code — authz, service_call A presigned blob URL was requested for a Realm whose asset policy declares routing_unlinkability_required=true. The service MUST deny presign and require an authenticated proxy, OHTTP relay, or equivalent non-bearer direct download path.
rsvp_basis_malformed reason_code — event_envelope, schema_validation entry.schedule_basis_refs does not carry exactly one well-formed ak:event: typed id: it is empty, holds more than one item, repeats an item, or the item is not a valid typed Event id. This shape admission is decidable from the payload field alone, without resolving the referenced Event, and MUST reject rather than pend. See zh/models/calendar-event.md section 8.1.
rsvp_occurrence_not_canonical reason_code — event_envelope, schema_validation payload.occurrence is neither JSON null nor a canonical instance key (YYYY-MM-DD for all-day, YYYY-MM-DDTHH:MM:SS[Zone] for timed), including when its date component is not a real proleptic-Gregorian date. Receivers MUST reject instead of rewriting the key, since the typed current result subject derives from the signed value. See zh/models/calendar-event.md.
runtime_key_missing reason_code — agent_readiness Closed generic Agent readiness blocker: no active accepted runtime key exists. It is durable subject-level readiness state and MUST NOT be inferred from a missing session or target-Realm grant.
schema_violation code 422 both Parsed input does not satisfy the declared schema contract.
scope_incomparable reason_code — state_resolution Sub-reason for failed_precondition when a structural relation, parent, position, cascade, or reverse-projected fact would need to span two sibling Circle scopes in the same Realm. v1 reducers MUST NOT choose either Circle, union them, or promote the fact to Realm-default. See zh/models/circle.md §6.1.
scope_rebind_forbidden reason_code — state_resolution Sub-reason for failed_precondition when scope_circle_id rebind is attempted without an explicitly profile-permitted audited-high-risk path. Default reducer rejects rebinds to prevent silent historical-discussion migration. See zh/models/circle.md §6.1.
scope_ref_mismatch reason_code — event_envelope, auth_decision, state_resolution The signed Event `scope_ref` does not equal the security scope deterministically resolved from the target or referenced accepted object state. Receiver MUST reject the Event and MUST NOT rewrite or reducer-stamp the signed scope. See zh/models/circle.md §6.1.
scope_unavailable reason_code — state_resolution Sub-reason for failed_precondition when an object write references an effective scope whose Circle or parent Realm has been tombstoned/destroyed and cannot accept new writes. Projections may surface the same string as a non-error status marker. See zh/models/realm-and-space.md §2.6.1 and zh/models/circle.md §9.2.
segment_aead_failed reason_code — crypto, service_call Streaming-chunked AEAD attachment: a per-segment AEAD tag fails to verify. Receivers MUST reject the segment and abort the stream. See zh/crypto-media/media-and-blob.md §3.3.6.
segment_bounds_invalid reason_code — schema_validation, service_call Streaming-chunked AEAD attachment: a segment index is out of range, a segment length violates `segment_bytes`, or `segment_count` disagrees with the observed stream. Receivers MUST reject. See zh/crypto-media/media-and-blob.md §3.3.
segment_replay reason_code — crypto, service_call Streaming-chunked AEAD attachment: a segment index appears more than once in the stream. Receivers MUST reject. See zh/crypto-media/media-and-blob.md §3.3.6.
segment_sequence_invalid reason_code — crypto, service_call Streaming-chunked AEAD attachment (`ak.blob.stream_aead.v1`): segment indices arrive out of order, skip a value, or leave a gap. Receivers MUST reject. See zh/crypto-media/media-and-blob.md §3.3.6.
segment_stream_truncated reason_code — crypto, service_call Streaming-chunked AEAD attachment: the stream ended without a valid final segment (last_segment_flag never observed, or fewer segments than `segment_count`). Receivers MUST reject to resist truncation. See zh/crypto-media/media-and-blob.md §3.3.6.
selector_actor_wildcard_forbidden reason_code — auth_decision, schema_validation The resource selector attempted to use actor:*. v1 actor selectors MUST name a concrete DID; universal subject grants are not accepted.
selector_governance_wildcard_forbidden reason_code — authz, schema_violation Governance-plane resource selector wildcard (e.g. policy:*, schema:*, or a governance object:* selector) was used without the required mitigation (denied by deployment policy, or constrained with max_authority_depth=0 plus bounded expiry plus admin approval). Receiver MUST reject.
selector_missing_realm_scope reason_code — authz, schema_validation Sub-reason for schema_violation when a resource selector names a Realm-local kind without a realm_id, including the shorthand form where both the realm part and the object id are the wildcard. Parsers MUST reject the whole grant rather than silently treating the selector as global. See zh/authz/resource-selector-grammar.md sections 3.1 and 6.
selector_too_complex code 422 both Resource selector or constraint exceeds parser hard limits defined in resource-selector-grammar.md §3.3 (string length, resources[] length, token count, nesting depth, single-field length, required_claims item count, constraint nesting). Dual-registered as a service code and a reason_code (see reason_codes[]) so it can be emitted as a top-level error and audit / abuse-detection can separate suspected parser-DoS attempts from ordinary format errors. See zh/authz/resource-selector-grammar.md §5.
send_failed reason_code — state_resolution Invite delivery to the private target failed after the delivery service exhausted the retry budget. Used as a stable invite transition reason for ak.invite state projections; see zh/models/governance-objects.md and zh/sync/third-party-invites.md §6.1.
series_chain_broken reason_code — schema_validation, state_resolution, device_recovery ak.schema.key_backup.v1 envelope chain failed verification: a `supersedes_digest` does not match the canonical_json digest of its predecessor, or a non-genesis envelope is missing a predecessor accessible to the caller. See zh/identity/key-management.md §7.6 and zh/crypto-media/device-lifecycle.md §12 / §12.1.
series_predecessor_not_found reason_code — schema_validation, state_resolution `ak.schema.key_backup.v1.supersedes` references a backup_id that is unknown to the server, deleted, or owned by a different actor / series. Wire endpoint returns 409 Conflict; receivers MUST treat the chain as broken. See zh/crypto-media/device-lifecycle.md §12.1.
series_seq_not_monotonic reason_code — schema_validation, state_resolution A PUT /_arkret/self/keys/backups/{backup_id} request whose `series_seq` is not strictly greater than the current maximum sequence within the same (actor_id, series_id), or whose genesis envelope sets series_seq != 0. See zh/crypto-media/device-lifecycle.md §12.1.
service_identity_conflict code 409 both The service registration key or declared public base is already bound to a different DID, inception operation, or control root. Providers MUST return this error instead of minting a fork.
service_identity_provider_unavailable code 503 service_call The configured Service Identity Provider is temporarily unreachable or unavailable. Callers may retry without changing the registration request.
service_identity_unavailable code 503 both The target service cannot serve the request because its runtime service identity is not ready. The response SHOULD carry Retry-After when retry timing is known.
service_key_revoked reason_code — federation_transaction, auth_decision Diagnostic key-state fact. On closed peer event submit, a revoked origin service signing key fails current transport authentication as signature_invalid before any idempotency lookup; this reason is not a replay-success response. See zh/conformance/conformance-vectors.md §3.9.
service_not_plaintext_visible reason_code — service_call, auth_decision Service is not in the Realm's plaintext_visible_services policy; plaintext-bound operation refused.
service_prerotation_invalid reason_code — identity_resolution, service_call A service did:webvh inception or rotation omitted the sole next-key commitment, supplied more than one update/next key, or failed to open the previous nextKeyHashes commitment. Providers and resolvers MUST fail closed as service_registration_denied.
service_registration_denied code 400 both A service-registration request is well formed but its signed inception, service type, canonical public base, or control proof violates the Provider profile.
service_route_fork reason_code — identity_resolution, federation_transaction The method-native service evidence conflicts with the durable accepted DID history prefix.
service_unavailable code 503 both The service or a required upstream dependency is unavailable; callers MAY retry according to Retry-After / next_retry_at when provided.
session_focus_already_committed reason_code — event_envelope A subsequent `ak.call.state` event attempted to write a `session_focus` value different from the already-committed one. The reducer MUST `failed_precondition` — `session_focus` is write-once per call lifecycle; in-session focus migration is not supported in v1. See zh/crypto-media/call-state.md §4.1.
session_focus_no_split_brain reason_code — service_call The committed `ak.call.state.session_focus` is authoritative and write-once: once it exists, a connect / token-exchange failure against that focus MUST be surfaced as focus-unavailable (`focus_unavailable_for_client`) and clients MUST NOT silently fall back to a different focus to keep the media path up. Naming the invariant explicitly closes the split-brain attack where two subsets of a conference converge on different SFUs. See zh/crypto-media/media-service-binding.md §5 and §2 (`foci[].health_endpoint`).
session_grant_not_found code 404 endpoint `ak.gate.account.command.revoke_session.v1` targeted a session grant that is unknown, already inactive, or not owned by the current principal. Implementations SHOULD use a uniform response shape that does not disclose another principal's session grant existence.
session_grant_replay_expired code 410 endpoint A durable exact-replay lookup found the original SessionGrant issuance outcome, but its immutable expires_at is past. The response details MUST include grant_id and state=expired. The issuer MUST NOT return the expired credential as success or issue a replacement under the same request identity; the client must perform full authentication with a new one-shot proof and request identity.
session_grant_replay_indeterminate code 409 endpoint The stable SessionGrant request identity is older than the issuer's durable replay-record retention window, so the issuer cannot prove whether the one-shot request previously committed. It MUST fail closed and MUST NOT treat the request as first issuance; the client must obtain a new one-shot proof and request identity.
session_grant_replay_terminal code 409 endpoint A durable exact-replay lookup found the original SessionGrant issuance outcome in revoked or superseded state. The response details MUST include grant_id and the exact terminal state. The issuer MUST NOT return the credential as success or issue a replacement under the same request identity; the client must perform full authentication with a new one-shot proof and request identity.
session_logged_out code 400 endpoint Session-grant rotation refused because the underlying Auth Server browser session has been logged out (finished). The rotation chain cannot be resumed; full re-authentication is required. See account-lifecycle §4.1.
session_missing reason_code — direct_conversation_readiness Closed target-specific Direct Conversation readiness blocker: the otherwise authorized Agent has no current session for the requested send path. It MUST NOT appear in generic Agent readiness.
session_revoke_selector_conflict code 422 endpoint `ak.gate.account.command.revoke_session.v1` supplied more than one mutually exclusive selector (`target_session_grant_id`, `target_device_id`, `all_sessions=true`) or otherwise failed selector closure. Receivers MUST reject instead of choosing one selector implicitly.
sfu_not_allowed code 403 service_call Requested SFU or media focus is not allowed by Realm policy or media service binding.
sidecar_create_denied reason_code — auth_decision, state_resolution, service_call Agent Sidecar ensure was denied without revealing whether the controller's native Sidecar or requested source-context mapping already exists. Returned as a generic failed_precondition sub-reason to avoid existence side channels. See zh/models/sidecar.md §3 and §7.
signal_class_denied code 403 service_call ak.self.signal.command.send.v1 rejected the envelope because an outer-visible signal_class, current participant/membership/scope authority, or Realm policy gate failed. The Station cannot inspect encrypted product kind or target; all such outer admission failures use this non-enumerating code without naming the failed input.
signal_plaintext_forbidden reason_code — service_call, client_sync Sub-reason for failed_precondition when any plaintext broadcast envelope is submitted or received. Signal is encrypted-only in every scope; implementations MUST fail closed and MUST NOT advertise Signal for a scope unless they can verify its MLS basis, AAD, and proof. See zh/sync/signal.md §1 and §3.
signal_rail_unavailable code 503 service_call ak.self.signal.command.send.v1 could not enqueue or fan out the transient signal because the signal channel is temporarily unavailable; durable Event history is not affected.
signal_ttl_out_of_range code 400 service_call ak.self.signal.command.send.v1 rejected the outer envelope lifetime because it is absent when required or outside the service's advertised signal_class-specific range.
signature_invalid code 401 both A required signature or proof does not verify.
signature_window_invalid code 401 endpoint An RFC 9421 HTTP Message Signature failed the freshness window: created/expires missing or not integers, the claimed lifetime outside the registered ceiling, created outside the registered receiver skew, or expires already reached. It also covers byte-identical replays after the bounded replay cache evicted the entry. The window algorithm and its numerals are owned by http_signature_contract_registry in registry/contract-registry.json and stated in zh/sync/service-http-binding.md section 8.3; no other page or artifact carries those numerals. Scenario-specific tightening is registered as a freshness profile there, currently only for ak.peer.signal.command.relay.v1. Applies to every registered signing scenario, including Applet transaction push (zh/extensions/applet-integration.md section 7.3.1) and MIMI provider-to-provider writes (zh/extensions/mimi-interop.md section 5).
snapshot_capacity_exceeded reason_code — event_envelope, auth_decision The candidate RealmCommit would make the maximal-disclosure, current governance Station-signed inline Realm State Snapshot exceed 8 MiB of complete RFC 8785 canonical signed bytes. Every operation branch that first admits an Event and signs a RealmCommit rechecks the final durable cut in the same transaction; overflow returns top-level failed_precondition (HTTP 409) with this reason_code and zero Event, RealmCommit, typed current, and snapshot writes. Exact 8 MiB is allowed. See zh/conformance/scalability-constraints.md section 4.1 and fixtures/scalability-limits-fixture.json.
soft_logged_out code 401 both Session was soft-logged-out and must be refreshed.
source_refs_unverifiable code 400 service_call Directory ingest or cross-service projection could not verify declared source_refs against the authoritative Station, resource source, or signed projection checkpoint.
space_already_terminal reason_code — event_envelope, auth_decision `ak.space.tombstone` rejected because the target Space is already `tombstoned`.
space_has_live_dependents reason_code — event_envelope, auth_decision Space tombstone is blocked by a non-tombstoned child Space or an effective canonical placement of a non-redacted Strand. Archived dependents still count. See zh/models/realm-and-space.md section 3.4.
space_not_active reason_code — event_envelope, auth_decision `ak.space.archive` rejected because the target Space is not in `active` state (per zh/models/realm-and-space.md §3.3).
space_not_archived reason_code — event_envelope, auth_decision `ak.space.restore` rejected because the target Space is not in `archived` state; `tombstoned` is a terminal state and MUST NOT be restored.
space_parent_cycle reason_code — event_envelope, auth_decision `ak.space.parent` would create a cycle in the Space ancestor chain (self-loop or chain loop). Reducer MUST reject (zh/models/realm-and-space.md §3.5).
space_parent_mismatch reason_code — event_envelope, state_resolution The expected_parent_space_id declared by an ak.space.parent payload and the parent_space_id stored in that Space's space_parent register are not byte-equal. Both are always present -- the payload member is required and the register is written for every Space by the ak.space.create genesis write -- so this is a two-valued equality, not the three-valued stored_field_matches_payload the directed-invite slot needs. Reducer MUST reject with zero writes (zh/models/realm-and-space.md section 3.5).
space_parent_unreadable reason_code — event_envelope, auth_decision, projection Canonical parent or placement structural facts cannot be read or verified at the operation basis. Structural validation and subtree authorization MUST fail closed, without disclosing hidden target Realm identity.
space_realm_mismatch reason_code — event_envelope, auth_decision A verified canonical Space parent or Board/List/Strand placement crosses actual Realm identities. Reject with failed_precondition after target readability and evidence checks; no profile exception or automatic Realm rewrite.
spam reason_code — moderation_report Standard moderation reason: spam content.
state_mismatch code 409 both Encrypted content or MLS epoch is bound to an application state root that cannot be verified against accepted state.
status_unavailable code 503 service_call Required credential revocation or status material is temporarily unavailable.
storage_failed reason_code — event_envelope, service_call Capture artifact persistence or deletion failed in the Arkret blob pipeline.
strand_already_terminal reason_code — event_envelope, auth_decision A `ak.redaction` event targeting a Strand is rejected because the target Strand is already in terminal state `redacted`. Strand terminal state is reached via ak.redaction.
strand_not_active reason_code — event_envelope, auth_decision `ak.strand.archive` / `ak.strand.update` rejected because the target Strand is not in `active` state (per zh/models/common-fields.md §5.1).
strand_not_archived reason_code — event_envelope, auth_decision `ak.strand.restore` rejected because the target Strand is not in `archived` state.
stream_dropped code 409 endpoint A subscription stream dropped events or account updates and the client must follow the server-directed recovery path.
stream_resync_required code 409 endpoint A subscription stream cannot safely continue from the supplied cursor; the client must resync from a fresh cursor or snapshot.
stream_tail_missing reason_code — client_sync One authorized commit stream cannot be continued from the caller's durable cursor: the tail range between that cursor and the stream's current head is unavailable to this service (retention or history floor reached, or the durable range is otherwise not servable). It is per-stream and scoped to exactly one stream_ref, so the client re-acquires the snapshot and tail for that stream alone and MUST NOT reset other Realm / Circle / Sidecar streams, the account baseline or to-device ACKs. It is NOT the same as an empty tail: an authorized stream that is simply at its head returns zero items and `accepted`. emitting this code for a stream the caller may not read, or for one that does not exist, would turn that anti-enumeration bucket into an oracle. Only a stream the caller is currently authorized to read may be reported with it. See zh/sync/client-sync.md section 3.
structure_depth_exceeded reason_code — encoding, schema_validation A canonical JSON or deterministic CBOR structure exceeds the v1 maximum nesting depth of 64 (objects and arrays combined, top-level container = depth 1). Receiver MUST reject (top-level schema_violation) before recursive descent can exhaust the stack, and MUST NOT truncate or partially parse. See zh/conformance/scalability-constraints.md section 2.
superseded reason_code — device_recovery Recovery-session `rejection_reason_code` value: the session was superseded by a newer recovery session for the same principal / device. Closed value set defined in artifacts/schemas/recovery-session.schema.json; completion ownership is defined in zh/identity/security-transactions.md §2.
superseded_by_repairing reason_code — event_envelope, auth_decision Reducer audit reason stamped when one controller-signed ak.agent.key.authorize runtime-replacement Event atomically observe-removes every prior active authorization dot named by its exact supersedes[] set and adds the new authorization. No synthetic ak.agent.key.revoke Event is authored. Sessions issued from superseded keys MUST fail closed within the revocation freshness window. See zh/identity/key-management.md §3.6.1.
temporarily_unavailable code 503 endpoint The service is temporarily unavailable or cannot currently satisfy the request.
test_signing_material_denied reason_code — auth_decision, identity_resolution, proof_verification, crypto The presented signing material or identifier is registered in artifacts/registry/test-material-registry.json as published test material or as a reserved test identifier, so it MUST NOT be admitted on a formal verification, authorization or trust-admission path even when the signature verifies: its private key ships with the specification. The refusal is fail-closed and MUST NOT leave a verified binding, a resolution cache entry or accepted auth state behind, MUST NOT degrade to a weaker evidence class, a limited_trust pin or a retryable unavailable, and MUST NOT be reachable through a configuration switch on the formal API. See zh/identity/did-usage-and-verification.md §8.
third_party_invite_acceptance_missing reason_code — service_call, auth_decision Sub-reason for failed_precondition when ak.open.third_party_invite.command.activate.v1 has no usable Station acceptance attestation for the named invite: the attestation signature does not verify against the attesting Station service identity, its audience or verification_id is not this service, or it does not attest a pending ak.invite.third_party on an accepted basis. A caller-reported invite id, a caller-computed invite digest, an Event signature or an HTTP success MUST NOT be accepted in its place. See zh/sync/third-party-invites.md section 7.5.
third_party_invite_acceptance_stale reason_code — service_call, auth_decision Sub-reason for failed_precondition when a Station acceptance attestation is structurally valid but its signed expires_at has passed, observed_at is later than expires_at, or expires_at exceeds invite_expires_at. The verification service MUST fail closed rather than bind private invite material with an invalid or expired attestation. See zh/sync/third-party-invites.md section 7.5.
third_party_invite_material_mismatch reason_code — service_call, auth_decision Sub-reason for failed_precondition when the accepted ak.invite.third_party attested for activation differs from the frozen provisioning record in author, Realm, expiry or any member of the public third_party_invite object. The verification service MUST refuse rather than adopt the accepted typed current result values, because its private token, salt or pepper and ephemeral key were generated for the frozen material. See zh/sync/third-party-invites.md section 7.5.
third_party_invite_provisioning_already_bound reason_code — service_call, auth_decision Sub-reason for duplicate_conflict when an activation attempt would bind an already bound provisioning record to a different invite, Realm or author. One provisioning record binds to exactly one invite for its whole life; the service MUST NOT rebind, rotate the ephemeral key or reissue the token. See zh/sync/third-party-invites.md section 7.5.
third_party_invite_provisioning_expired reason_code — service_call, auth_decision Sub-reason for failed_precondition when activation is attempted after the provisioning record activation_expires_at. The record is cleaned up on the zh/sync/third-party-invites.md section 6.1 schedule and MUST NOT be revived; the inviter provisions fresh material and authors a new invite.
third_party_invite_token_in_query reason_code — service_call, auth_decision A 3PID invite claim arrived with the invite_token sourced from a URL query string or path segment instead of from a URL fragment or out-of-band code, in violation of zh/sync/third-party-invites.md §3.2. The verification service MUST reject and SHOULD invalidate the token to prevent referer / log replay.
timeout code 504 both A wait-for, long-poll, or upstream dependency timed out.
token_expired reason_code — service_call, auth_decision A media backend join token presented at connect time is past its `expires_at` (e.g. a LiveKit JWT whose `exp` has elapsed, distinct from `proof_invalid` which covers a structurally bad / wrong-issuer signature). The client MUST re-run the media-service-binding §3 token exchange instead of reusing the stale token; clients MUST NOT extend or replay an expired backend token. See zh/crypto-media/bindings/livekit.md §8 and zh/crypto-media/bindings/arkret-native.md.
token_issuer_unauthorised reason_code — service_call, auth_decision A media token's `service_signature.kid` or `participant_binding.issuer_kid` resolves to a service DID that does NOT appear in the current epoch `ak.realm.media_service.service_id` (or the foci[]-aligned token endpoint authority commit). Clients MUST reject — this closes the attack where any service can forge a focus join token. See zh/crypto-media/media-service-binding.md §3.
too_large code 413 both Generic request, query, batch, or envelope size limit exceeded. More specific blob/push/payload variants may be used when available.
track_disabled code 409 both The target Strand track has enabled=false and does not accept new writes (synthesis edits or track-scoped patches). Generic freeze code for any track; discussion_track_disabled is the discussion-track-specific specialization for ak.message.* writes. See zh/models/strand-and-message.md §4.1 / §4.7.
transcription_artifact_pipeline_bypassed reason_code — service_call A backend attempted to deliver a transcription artifact outside the Arkret-side blob pipeline, or used a key not derived from the MLS-Exporter label `ak.rtc-transcript-key/v1` (e.g. reused the SFrame / recording label or an empty Context). Clients MUST fail closed. See zh/crypto-media/call-state.md §5.1 and zh/crypto-media/media-service-binding.md §8.1.
transcription_denied reason_code — service_call, auth_decision Call transcription was requested without `ak.call.transcribe` capability, or the Realm policy forbids transcription. Issuer / reducer MUST reject; parallels `recording_denied` for the transcribe dimension. See zh/crypto-media/call-state.md §5.1.
ttl_expired reason_code — event_envelope, auth_decision, state_resolution A bounded-lifetime artefact (member application, reservation typed current result, presign envelope, runtime gate proof, etc.) is past its declared `expires_at` / TTL window. See per-feature spec sections.
turn_credential_expired code 401 endpoint TURN REST-style ephemeral credential is past its TTL; client MUST request a fresh credential. See zh/crypto-media/webrtc-signaling.md §4.1.
unauthenticated code 401 both Authentication material is missing or invalid.
unknown_event_kind reason_code — event_envelope Event kind does not appear in the current registry. Fail closed; an unknown kind is not a non-critical extension and current-v1 has no generic critical_extensions carrier that can make it admissible.
unknown_field reason_code — event_envelope Current parser rejected an Event carrying a top-level or payload field not declared by the closed schema for its kind (including removed / renamed fields in artifacts/registry/forbidden-wire-fields.json). Distinct from `schema_violation` in that it pinpoints an unrecognized field rather than a constraint violation on a known field. See zh/overview/current-contract.md §1.
unknown_focus_type reason_code — service_call, schema_validation A `ak.realm.media_service.foci[].focus_kind` value is not in the v1 registered set (`livekit` / `mediasoup` / `janus` / `arkret_native` / `moq_relay`) or is registered but not supported by this client / issuer. Clients MUST fail closed instead of forwarding the token to an arbitrary SDK. See zh/crypto-media/media-service-binding.md §2.
unknown_kind reason_code — event_envelope Current parser rejected an Event whose `kind` is not an active registered v1 kind. Sync, federation, snapshot, SDK, and conformance paths MUST fail closed and MUST NOT perform payload-shape disambiguation or alias lookup. See zh/overview/current-contract.md §1.
unrecognized_endpoint code 404 endpoint The path is inside the protocol namespace but not implemented by the service.
unresolved_basis reason_code — state_resolution, projection A projected RSVP head references a schedule basis that cannot be resolved, is invisible, or is not on the target Strand's schedule revision DAG. The head is retained for audit, excluded from the effective response, and MUST NOT be guessed into currency. See zh/models/calendar-event.md.
unsupported_aead_profile reason_code — crypto, schema_validation Receiver does not recognise `encryption.aead.aead_profile` (or sees a reserved-but-unpublished profile such as `ak.aead.hybrid_kem.*`). Receivers MUST fail closed; inferring parameters from `aead.name` alone is forbidden. See zh/identity/key-management.md §7.9.
unsupported_attachment_scheme reason_code — schema_validation, service_call An encrypted-attachment envelope carries a `scheme` value the receiver does not recognise. Receivers MUST fail closed rather than guess a decryption form. See zh/crypto-media/media-and-blob.md §3.2/§3.3.
unsupported_ciphersuite code 422 both An MLS ciphersuite selector is not an active row of artifacts/registry/mls-ciphersuite-registry.json (unknown, inactive, or reserved-but-not-activated) during KeyPackage publish, claim or Commit submission. One of the four algorithm-agility fail-closed errors; dual-registered as a service code and a reason_code (see unsupported_digest_algorithm). Receivers MUST fail closed even if the underlying MLS library supports the suite. See zh/crypto-media/encryption-and-audit.md §2.1.
unsupported_content_encoding code 415 both A canonical non-streaming JSON operation carried a Content-Encoding header. Canonical JSON bindings MUST reject the request before reading or decompressing the body; see zh/conformance/scalability-constraints.md section 2.1.4.
unsupported_did_method code 422 endpoint The DID method is syntactically valid but not supported by the active identity registry or resolver policy.
unsupported_digest_algorithm code 422 both The digest suite prefix in a typed digest value (e.g. sha256:<hex>, cbor.sha256:<hex>) is not an active row of artifacts/registry/digest-suite-registry.json supported by the receiver (unknown id, unregistered tuple, or reserved suite) on a critical field. See zh/conformance/encoding.md §3.1-§3.2. Dual-registered (also a reason_code): all four algorithm-agility fail-closed errors (unsupported_digest_algorithm / unsupported_signature_alg / unsupported_hpke_suite / unsupported_ciphersuite) appear in both `codes` (top-level service error) and `reason_codes` (per-item sub-reason); see zh/conformance/schema-registry.md §1.1.1.
unsupported_event_kind code 501 both The service does not accept the requested active standard Event kind.
unsupported_feature code 501 both A required protocol feature is not supported. It also carries the per-item rejection for a structurally valid Event whose producer class or wire feature has no admissible v1 form, such as an rfc9420.proposal decoded to an unsupported RFC 9420 sender class or Proposal type (mls-proposal-admission-registry.json); that case MUST NOT be reported as schema_violation. Dual-registered as a reason_code for the event_envelope scope (see reason_codes[]).
unsupported_hpke_suite code 422 both HPKE suite id on an application-layer committed surface is not an active row of artifacts/registry/hpke-suite-registry.json (unknown, inactive, or reserved-but-not-activated). One of the four algorithm-agility fail-closed errors; dual-registered as a service code and a reason_code (see unsupported_digest_algorithm). Receivers MUST fail closed rather than infer suite parameters from the AEAD name. See zh/identity/key-management.md §7.5.2.
unsupported_join_rule code 422 both A third-party (3PID) invite claim targeted a join-rule Realm whose continuation profile is outside v1 base conformance (e.g. knock_restricted) and the deployment has not declared the required candidate profile in ak.find.directory.read.describe.v1 / ak.account.describe. The verification service MUST reject the token claim instead of silently downgrading. See zh/sync/third-party-invites.md §4.3.
unsupported_media_policy code 422 endpoint The requested media, call, recording, or SFU policy is not supported by the service or negotiated media profile.
unsupported_operation_version code 422 both The supplied exact versioned operation selector is duplicated, unknown, not advertised on the selected carrier, or outside the selected endpoint family; this code also applies when the endpoint family has no advertised exact candidate. Receivers MUST fail closed without version fallback, alias resolution, or payload-shape inference.
unsupported_organization_registration_scope code 422 endpoint A requested delegated scope is outside the closed organization registration scope set, or this deployment does not offer it. The scope vocabulary is closed so that a deployment cannot mint administrative authority the organization never consented to.
unsupported_profile code 422 both The selected operation or portable artifact requires a profile or feature the service does not implement. Capabilities use supported_features / supported_profiles. The server MUST fail closed and MUST NOT substitute a local default or permissive interpretation. Dual-registered as a per-device reason_code for ak.edge.push.command.notify.v1 (see reason_codes[]).
unsupported_profile_patch_path code 422 endpoint `ak.self.account.command.update_profile.v1` received a patch path outside the account self-service allowlist (`display_name`, `avatar_blob_ref`, `profile_fields.<key>`). Handle, lifecycle, principal, actor_kind, accountability, authorization, and handle-claim paths MUST be rejected instead of silently ignored.
unsupported_proof_profile code 422 service_call Wallet and verifier have no mutually supported proof profile for the requested presentation.
unsupported_protocol_version code 422 both A syntactically well-formed protocol-family bootstrap discriminator is not supported by the receiver. For v1 ServiceDescribe and equivalent ping surfaces, a protocol_version string other than the canonical value 1.0 makes the complete service unusable before capability intersection or route caching. Missing or non-string values remain schema_violation. A binding that implements Arkret-Protocol-Version header or equivalent media-type negotiation returns this code for an unsupported requested version. Dual-registered as a top-level service code and a reason_code. See zh/overview/current-contract.md §1 and §4.
unsupported_signature_alg code 422 both Proof / event signature `alg` is not in the conformance signature-algorithm allowlist (artifacts/registry/signature-alg-registry.json) on a critical field. One of the four algorithm-agility fail-closed errors; dual-registered as a service code and a reason_code (see unsupported_digest_algorithm). See zh/conformance/encoding.md §6.1.
untrusted_backup_signature reason_code — crypto, device_recovery, state_resolution A key-backup envelope signature verifies cryptographically but the signer is not an active accepted device in the current generation, or is revoked, unauthorized, or generation-mismatched. Receivers MUST reject it even if the series chain and ciphertext_digest are self-consistent. See zh/identity/key-management.md §7.4.1.
upstream_unavailable code 503 endpoint A required upstream dependency is temporarily unavailable. HTTP bindings MUST use 503 Service Unavailable and SHOULD include Retry-After when a retry window is known; 412 is reserved for failed request preconditions.
verification_method_principal_mismatch reason_code — auth_decision, service_call A request supplied a `verification_method` whose DID component does not bit-identically match the target principal id after stripping fragment/query. Surfaces in two places. (1) `ak.gate.account.command.pair_agent_key.v1`: `verification_method` vs `agent_id`. (2) `ak.gate.account.command.issue_session_grant.v1` agent branch (`proof.proof_kind="agent_key_proof"`): `proof.verification_method` vs request `principal_id`. Endpoints MUST fail closed before invoking the proof validator so that mismatch is reported as this code rather than as a generic signature failure. See zh/identity/key-management.md §3.6.1.
verifier_unauthorized code 403 service_call A presentation verifier could not prove authority to represent its claimed organization or relying party.
view_already_terminal reason_code — event_envelope, state_resolution An ak.view.update or ak.view.reconcile targeted a View whose accepted lifecycle state is tombstoned, or attempted to restore that View to active. Tombstoned shared Views are terminal. See zh/models/views.md §3.1.
watch_level_public_must_be_self reason_code — auth_decision `ak.strand.watch.set` writing `level_public=true` for another actor is rejected — publishing one's own subscription level is an opt-in personal disclosure and MUST be written by the target actor themself. `ak.strand.watch.set.others` writes MUST omit `level_public` or set it to `false`. See zh/models/strand-and-message.md §8.4.
watch_must_be_self reason_code — auth_decision `ak.strand.watch.set` may only set the watch state of the submitting actor; cross-actor writes require `ak.strand.watch.set.others` (audit / accessibility scope). See zh/models/strand-and-message.md §8.4.
watch_muted_must_be_self reason_code — auth_decision `ak.strand.watch.set` writing `level="muted"` for another actor is rejected — `muted` suppresses mention / moderation / workflow notifications and MUST be opt-in by the target actor themself. `ak.strand.watch.set.others` only authorizes writing `level ∈ {mentions_only, participating, all}` for other actors. See zh/models/strand-and-message.md §8.4.
watch_set_others_audit_missing reason_code — auth_decision A `ak.strand.watch.set` write that uses `ak.strand.watch.set.others` to set another actor's watch state was rejected because it lacked semantic_refs[role=audit_pair] to a same-batch `ak.audit.accessed` event, or the paired audit payload did not identify the same writer DID, target actor DID, typed current result id, paired event id/digest, and before/after heads. See zh/models/strand-and-message.md §8.4.
webvh_cache_too_stale reason_code — auth_decision, service_call A did:webvh resolver cache entry exceeded the per-entry maximum evidence age, even if the global cache-only outage window has not expired. High-risk writes, service delegation, capability reconstruction, and snapshot witness acceptance MUST fail closed. See zh/identity/identity-did.md §5.
webvh_cache_unavailable reason_code — identity_resolution did:webvh resolution is in cache-only degraded mode and either the requested operation is outside the closed low-risk read-only set, or no committed, controller-proof-verified cache evidence is available. Resolver MUST fail closed rather than treat unresolvable as valid.
webvh_witness_controlling_organization_unverified reason_code — identity_resolution, auth_decision A deployment profile requires witnesses from distinct controlling organizations, but the controlling organization of at least one witness cannot be verified, or two witnesses resolve to the same organization. Counting unverifiable or colliding organizations would let one operator running several witness keys satisfy a distinct-organization requirement alone; the verifier MUST fail closed on high-risk paths. See zh/identity/identity-did.md §3.4.2.
webvh_witness_evidence_stale reason_code — identity_resolution, auth_decision Witness evidence is older than the effective max age set by deployment / Realm policy, measured from when the proof was observed rather than from when any Arkret receipt was signed. Re-signing an old observation does not refresh it. See zh/identity/identity-did.md §3.4.2.
webvh_witness_parameter_malformed reason_code — identity_resolution, auth_decision parameters.witness is present but is not the did:webvh 1.0 shape {threshold, witnesses:[{id}]}: threshold outside 1..witnesses.length, a duplicated witness id, a witness id that is not a did:key, a did:key whose multibase/multicodec payload does not decode to a well-formed public key compatible with the log's Data Integrity cryptosuite, or an unregistered extension key. Key decoding happens during parameter validation, not at signature time; accepting a witness id on string shape alone would let an unverifiable key occupy a threshold slot and hollow out the threshold. Also raised when parameters carries a look-alike key such as witnesses, witness_threshold or witnessThreshold, because that shape is evidence the log was produced against a non-standard dialect and the true policy is therefore unknown. A verifier MUST fail closed and MUST NOT fall back to treating the DID as unwitnessed: silently reading a malformed or aliased declaration as threshold 0 turns a DID that declares witnesses into one that requires none. See zh/identity/identity-did.md §3.4.1.
webvh_witness_proof_invalid reason_code — identity_resolution, auth_decision A witness proof in did-witness.json fails signature verification, is signed by a key outside the witness listed in parameters.witness, or does not bind the versionId it is offered for. The proof does not count toward threshold and the entry MUST be treated as under-witnessed. See zh/identity/identity-did.md §3.4.1.
webvh_witness_proofs_unavailable reason_code — identity_resolution, auth_decision parameters.witness declares a witness policy but the did-witness.json proofs file is unreachable, unparseable, or contains no entry for the versionId under evaluation. Unavailable evidence is not absent policy; the verifier MUST fail closed on high-risk paths rather than proceed as if no witnessing were required. See zh/identity/identity-did.md §3.4.1.
webvh_witness_threshold_not_met reason_code — identity_resolution, auth_decision Valid distinct witness proofs for the versionId are fewer than the effective threshold, which is the strictest intersection of the method-native parameters.witness.threshold and the deployment / Realm policy minimum. A holder-declared policy can raise this bar but MUST NOT lower it. See zh/identity/identity-did.md §3.4.1 and §3.4.2.
welcome_capability_mismatch reason_code — event_envelope, crypto An MlsWelcomeDelivery claim reference does not match the claimed KeyPackage capabilities. The recipient MUST reject the delivery before decrypting it.
witness_disagreement reason_code — state_resolution, federation_transaction Confirmed fork evidence: two byte-distinct canonical Event preimages pass structure, suite and proof prerequisites and independently recompute to the same complete suite-tagged event_id (full-hash collision evidence); two byte-distinct signed RealmCommit objects name the same (stream_ref, stream_position); or a profile declares the observed combination non-joinable. A carried event_id whose recomputed digest differs is only event_id_digest_mismatch and MUST be rejected before quarantine. Two different accepted Events by one actor are not by themselves disagreement: an actor may author any number of Events and event-and-patch.md section 2.6 gives ordering precedence to the RealmCommit alone, so only one stream position carrying two distinct commits is equivocation. Raw stream head differences observed across different replication or disclosure scopes also are not disagreement: a consumer only ever observes the heads of the streams it is granted. The verifier MUST quarantine only the affected evidence scope and fail closed; recovery requires raw replay plus an accepted operator-approved fork resolution. See zh/sync/operations-sync.md §12 and zh/sync/federation.md §4.5.1.