Terminal Actor State
URI: https://docs.ankatech.co/errors/terminal-actor-state
HTTP Status: 422 Unprocessable Entity
When you see this
You asked an Internal Crypto Use Case* to suspend or resume, and the Cryptographic Actor that aggregate owns is DISABLED. DISABLED is terminal and irreversible, so the actor can never act again — which makes the aggregate both un-suspendable and un-resumable.
This is a distinct 422 from Invalid State Transition, and the distinction is the point: that one means the current state does not permit this verb, and a different verb — or the same verb later — succeeds. This one means no verb on this aggregate will ever succeed again. A client must be able to tell those apart on the type member rather than by string-matching detail, which is prose and may be reworded.
The refusal is raised inside the transition's own transaction, before the aggregate row is written, so nothing was changed: the aggregate keeps the status it had.
Common Causes
- The owning tenant was closed, and the closure cascade terminal-disabled the actor.
- The owning Application was deleted, and its delete cascade terminal-disabled the actor.
Neither is a mistake on the use case's part — the actor reaches DISABLED independently of the aggregate, which is why this state is reported as a recognisable condition rather than as a generic invalid transition.
Response Example
{
"type": "https://docs.ankatech.co/errors/terminal-actor-state",
"title": "Terminal Actor State",
"status": 422,
"detail": "Use case cannot be suspended: its Cryptographic Actor is DISABLED, which is terminal and irreversible, so the workload can never act again. The actor reaches that state independently of this use case — a tenant closure, or the owning Application's delete cascade. Exit: revoke this use case (DELETE) to bring the aggregate to a consistent terminal state, then provision a new one if the workload is still required.",
"instance": "/api/v3/admin/tenants/00000000-0000-0000-0000-000000000001/internal-crypto-use-cases/9f1c4d2e-7b83-4a51-95e6-2c0d81ab6f34/suspend",
"timestamp": 1730000000,
"extensions": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Content-Type: application/problem+json — the response follows RFC 9457 Problem Details.
How to Resolve
- Do not retry the transition. The actor's state is irreversible, so every retry answers this same refusal.
- Revoke the use case —
DELETE /api/v3/admin/tenants/{tenantId}/internal-crypto-use-cases/{useCaseId}?reason=...— to bring the aggregate to a consistent terminal state. Revoke tolerates aDISABLEDactor because disabled is the state it is driving towards. - If the workload is still required, provision a replacement use case. The referenced keys are untouched by any of this, so the new use case can name the same
kid.
For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.