Skip to content

Tenant Key Encryption Key Unavailable

URI: https://docs.ankatech.co/errors/tenant-kek-unavailable
HTTP Status: 503 Service Unavailable

When you see this

A tenant could not be given its own key-encryption key on a platform whose operator has declared a key-protection backend, so the operation was refused and nothing was persisted. On a declared deployment a tenant either holds all three layers of its key — the metadata row, the cache reference and the key on the backend — or the operation that would have created it fails. extensions.reason names which condition fired, and extensions.declaredBackend names the token the operator chose, when it is recognised. The response carries a Retry-After header.

Common Causes

  • NO_PROVISIONING_BACKEND — a backend is declared but this instance has no provisioning backend able to materialise a key.
  • NO_KEK_MATERIALIZED — a provisioning backend ran and returned no key metadata.
  • DECLARED_BACKEND_UNRECOGNIZED — the recorded declared backend is a value the key-protection registry does not recognise. The offending value is not echoed, and declaredBackend is omitted.
  • NO_CUSTODY_ON_CARRIER — a tenant assigned to an ANKA-managed Cloud KMS tier holds no usable ACTIVE custody row on that tier's carrier: no row, a row on a different carrier, or a row whose key reference is unusable. Raised by the key-backend resolve, which refuses rather than answer with no key coordinate — an absent coordinate would otherwise be read as "use the tier's key". Distinct from NO_KEK_MATERIALIZED: nothing was attempted; the custody registry was read and names no key for this tenant where it is currently routed. A tier repointed onto a different backend family reaches it without any provisioning having failed.

Response Example

{
  "type": "https://docs.ankatech.co/errors/tenant-kek-unavailable",
  "title": "Tenant key encryption key unavailable",
  "status": 503,
  "detail": "A key-protection backend is declared for this environment but the tenant key encryption key could not be established, so the operation was refused and nothing was persisted. Contact your platform operator.",
  "instance": "/api/v3/admin/tenants",
  "timestamp": 1730000000,
  "extensions": {
    "declaredBackend": "luna",
    "reason": "NO_PROVISIONING_BACKEND",
    "requestId": "e91b60c5-7a24-4f18-bd93-05c2e8471a6f"
  }
}

Content-Type: application/problem+json — the response follows RFC 9457 Problem Details.

How to Resolve

  1. Read extensions.reason. NO_PROVISIONING_BACKEND means the declared backend has no working provisioning path on this instance; NO_KEK_MATERIALIZED means the backend ran and produced nothing.
  2. For either of those, verify the declared backend is bound and reachable — GET /api/v3/admin/platform/setup/status and the key-backend connection test are the two reads to start from.
  3. For DECLARED_BACKEND_UNRECOGNIZED, the recorded declaration is not a value the registry knows; re-declare the backend through the platform setup surface rather than editing the stored value.
  4. For NO_CUSTODY_ON_CARRIER, re-assign the tenant's Edition: the assign provisions the tenant's own key on the tier's current carrier, which is the row the resolve could not find.
  5. Retry the operation once the backend can materialise a key. The refused call persisted nothing, so no half-provisioned tenant was left behind.

For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.