Skip to content

Key Protection Limit Reached

URI: https://docs.ankatech.co/errors/key-protection-limit-reached
HTTP Status: 409 Conflict

When you see this

A key-metadata update (PATCH /api/v3/admin/tenants/{tenantId}/keys/{kid}) named a protection limit that the key's current material has already reached. A reached limit is final for that material, so the update was refused. Nothing was written and no audit event was published.

The same refusal answers a key import that re-imports an existing key with a different expiresAt after the key's expiry has passed: restating the same instant, or leaving expiresAt out, is accepted.

The two protection limits are:

  • expiresAt — refused, whether the update sets a new value or clears it, once the key's expiry has passed;
  • maxUsageLimit — refused, whether the update sets a new value or clears it, once the key's usage count has reached it.

Each field is frozen only by its own limit: a key that has used up its usage limit but whose expiry is still ahead can still have its expiresAt changed. The other fields — displayName, description, exportable, softLimitExpiration and softUsageLimit — stay changeable on such a key.

Such a key reads status: expired, and its protectionStopReasons names the limit reached (EXPIRY_REACHED, USAGE_LIMIT_REACHED, or both). It no longer encrypts or signs, and it still decrypts and verifies what it protected.

Response Example

{
  "type": "https://docs.ankatech.co/errors/key-protection-limit-reached",
  "title": "Key Protection Limit Reached",
  "status": 409,
  "detail": "Key payments-signing-key has reached its usage limit, so 'maxUsageLimit' can no longer be changed. A reached limit is final for the key's current material: rotate the key to give it a new current material with its own expiry and usage limit.",
  "instance": "/api/v3/admin/tenants/9b2d4c1a-7e3f-4a8b-b6d2-1f0e5c3a9d47/keys/payments-signing-key"
}

The detail names every refused field and the limits reached. When both limits are reached and the update names both fields, both are named.

Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. There is no Retry-After: retrying cannot succeed.

How to Resolve

  1. Rotate the key (POST /api/v3/admin/tenants/{tenantId}/keys/{kid}/rotations). Rotation gives the key a new current material under the same key identifier, with its own expiry and usage limit — stated in the rotation request or carried forward from the current material — and a usage count of zero. The new expiry must lie in the future.
  2. Change the limit before it is reached. While a limit has not been reached it can be extended, shortened or cleared. A new maxUsageLimit must be greater than the uses already counted (a value at or below them is refused with 400 invalid-input), and a new expiresAt must be in the future.
  3. Stop a key deliberately with suspend or revoke, not by lowering its limits.

Standards basis

KMIP 1.4 lets a Protect Stop Date change only while the object is Pre-Active or Active and "as long as the Protect Stop Date has not been reached" (Table 112), never returns a Deactivated object to Active (§3.22, State), and does not change Usage Limits once allocation has begun (§3.21). NIST SP 800-57 Part 1 Rev. 5 ends a key's originator-usage period with re-keying (§5.3.5, §8.2.3.1) while its recipient-usage period continues. See the KMIP Specification 1.4 and NIST SP 800-57 Part 1 Rev. 5.

Related: Key Material Expired and Key Material Usage Exhausted — the refusals an encryption or signature receives from such a key; Invalid Key State — a metadata update naming a material field on a key that has no current material.