Key-State Seal Key Closure
URI: https://docs.ankatech.co/errors/key-state-seal-key-closure
HTTP Status: 409 Conflict
When you see this
The request does not fit how the key-state seal key is closed. Admin API proves the seal key it holds against the generation's stored record every few minutes. When the two do not match, the generation is closed by a mismatch, and only two actions may follow: a compromise rotation, or a reopening after investigation. Nothing was changed.
extensions.reason names the case:
extensions.reason | Returned by | Meaning |
|---|---|---|
MISMATCH_REQUIRES_COMPROMISE_ROTATION | POST /api/v3/admin/platform/key-state-seal-keys/rotations (rotateKeyStateSealKey) with "compromise": false | The active generation is closed by a mismatch, so an ordinary rotation is refused |
NOT_CLOSED_BY_MISMATCH | POST /api/v3/admin/platform/key-state-seal-keys/{generation}/reopen (reopenKeyStateSealKey) | The generation is open, or it was closed by backend refusals, so there is nothing to reopen |
A generation closed by backend refusals reopens by itself at the next successful proof, once the deployment KEK unwraps it again. It is never reopened by hand.
Common Causes
- An ordinary rotation was started after a mismatch closed the active generation.
- A reopening named a generation whose
proofClosedByis notMISMATCH.
Response Example
{
"type": "https://docs.ankatech.co/errors/key-state-seal-key-closure",
"title": "Key-State Seal Key Closure",
"status": 409,
"detail": "This key-state seal key generation is not closed by a mismatch, so there is nothing to reopen. Nothing was changed.",
"instance": "/api/v3/admin/platform/key-state-seal-keys/2/reopen",
"extensions": {
"reason": "NOT_CLOSED_BY_MISMATCH",
"requestId": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
}
}
Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. This is an Admin API body, so the correlation identifier is extensions.requestId; see Error Index & Overview.
How to Resolve
- Read
listKeyStateSealKeys(GET /api/v3/admin/platform/key-state-seal-keys) and check the generation'sproofClosedAtandproofClosedBy. - For
MISMATCH_REQUIRES_COMPROMISE_ROTATION, investigate the mismatch first: tampering, a deployment KEK that unwraps to different bytes, or a corrupted process. Then either start the rotation again with"compromise": true, which re-seals every row on its signed state-version floor without trusting either copy of the closed key (the floor signs a row's version, not its content), or reopen the generation withreopenKeyStateSealKeyonce the investigation showed the stored record is sound. - For
NOT_CLOSED_BY_MISMATCH, there is nothing to do: a generation closed by backend refusals reopens once the deployment credential can unwrap it again.
For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.