Skip to content

Key Material Expired

URI: https://docs.ankatech.co/errors/key-material-expired
HTTP Status: 409 Conflict

When you see this

A request asked a key to apply protection — to encrypt, to sign, or to be the target of a re-encryption or a re-signature — and the key's current material is past its expiry (expiresAt). An expired key no longer protects new data. Nothing was encrypted or signed, and nothing was written.

The key itself is not changed by the refusal: it keeps its status and its current material, and everything it already protected still decrypts and verifies. Rotating the key gives it a new current material that protects again.

Common Causes

  • The key's expiry has passed. The expiry is reached strictly after the expiresAt instant: a key still protects at the exact instant it expires, and is refused from the next instant on.
  • The stored expiry cannot be read. A key whose expiry is present but not a valid timestamp is treated as expired: the platform does not apply protection with a key it cannot show to be inside its validity period.
  • The key is past its expiry and has also used up its usage limit. A key in both states is answered with this problem, never with Key Material Usage Exhausted; the key's details list both reasons.

Response Example

{
  "type": "https://docs.ankatech.co/errors/key-material-expired",
  "title": "Key Material Expired",
  "status": 409,
  "detail": "Operation 'encrypt' is refused: the key's current material is past its expiry, or its expiry cannot be read. Rotate the key to protect new data; what it already protected can still be decrypted and verified.",
  "instance": "/api/v3/crypto/encrypt",
  "correlationId": "3f2b8c1e-6d4a-4f0b-9a7e-2c5d8e1f4a90",
  "timestamp": 1768472401,
  "extensions": {
    "code": "KEY_MATERIAL_EXPIRED"
  }
}

The detail names the refused operation (encrypt or sign) and never the key, its expiry or its usage. On a PKCS#7 conversion the refused signer or recipient is named under extensions.actor (index, role, leg), never by its key.

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

Where it is answered

Every operation that applies protection with a tenant key: POST /api/v3/crypto/encrypt, /sign, /sign-encrypt, /reencrypt and /resign; their streaming forms POST /api/v3/crypto/stream/encrypt, /stream/sign, /stream/sign-encrypt, /stream/reencrypt and /stream/resign; and POST /api/v3/migration/convert-pkcs7-to-jose and /migration/stream/convert-pkcs7-to-jose, for each signer and recipient. On a re-encryption or a re-signature only the target key (newKid) is refused — and, for a token addressed to several keys, a recipient the re-encryption keeps; the source key is read, not used to protect, so an expired source key is never refused here. On a streaming operation the refusal is decided before any output exists, so it arrives as this problem document, never as a 200 with a truncated body.

Decrypting and verifying are never refused for an expired key by this problem. Whether they are allowed is decided by the tenant's lifecycle policy alone, as for any key in the same lifecycle state.

Each refusal is recorded in the audit trail as a signed crypto operation with status DENIED and error code DENY_KEY_MATERIAL_EXPIRED, naming the refused key and its material version.

How to Resolve

  1. Rotate the key. Rotation gives the key a new current material, with its own expiry, under the same key identifier; applications keep using the same identifier. The expired material becomes RETIRED and keeps decrypting and verifying what it protected. A rotation is refused when the new expiry it states is not in the future.
  2. Do not try to extend the expiry. Once reached, a key's expiry is final: a key-metadata update that sets or clears expiresAt on an expired key is refused with Key Protection Limit Reached.
  3. Keep the expired key while its data is needed. It stays readable; do not delete it while the data it protected still has to be decrypted or verified.
  4. Rotate before the expiry. A key's soft expiry (softLimitExpiration) and the key-expiry alerts warn ahead of the hard expiry, so the rotation can happen before any request is refused.

Standards basis

NIST SP 800-57 Part 1 Rev. 5 separates a key's originator-usage period, during which it may apply protection, from its recipient-usage period, during which it may still process what it protected (§5.3.5, §5.3.6); re-keying is the remedy at the end of the cryptoperiod (§8.2.3.1). The expiry behaves like the KMIP Protect Stop Date. See NIST SP 800-57 Part 1 Rev. 5 and the KMIP Specification 1.4.

Related: Key Material Usage Exhausted — the same refusal for a reached usage limit; Key Protection Limit Reached — the metadata update refused once a limit is reached; Invalid Key State — the key's lifecycle state does not allow the operation.