Skip to content

Backend Key Coordinate Requirement Not Satisfied

URI: https://docs.ankatech.co/errors/deployment-backend-key-id-requirement
HTTP Status: 422 Unprocessable Entity

When you see this

The keyId you submitted does not satisfy the declared backend's own requirement: either the backend requires a key coordinate and none was supplied, or it accepts none and one was. The request was refused before anything was written and before anything was contacted — no coordinates were stored, no descriptor was published, and no outbound connection was opened.

The body is syntactically valid. What the platform refuses is the pair: this backend, with a key coordinate, or this backend, without one.

This refusal belongs to the deployment plane only. It is not a byok- problem type and must not be read as one: on the per-tenant BYOK plane a key coordinate is required for every family, PKCS#11 included, because there the coordinate names the tenant's own key and is meaningful. The refusal below cannot occur there, so a byok- name would name a plane where it is impossible.

The requirement is a property of the backend family, declared once beside the platform's backend vocabulary and read by one component. It is published on the declarable-backend read as coordinateContract.keyIdRequirement, so a form renders it rather than re-deriving it:

Declared backend keyId What it is
aws-kms required the key ARN
gcp-kms, gcp-kms-hsm required the Cloud KMS resource path
azure-kv required the vault key name
azure-kv-mhsm required the Managed HSM key name
softhsm, nshield, luna, cloudhsm not accepted nothing — the platform derives the key's name itself on a PKCS#11 token, so there is no coordinate for an operator to supply

The vocabulary is two-valued, REQUIRED and NOT_ACCEPTED. There is no optional third value, because no backend row carries one.

It does not follow the endpoint requirement, and a form that assumes it does is wrong

The two columns are different partitions of the same nine tokens. endpointRequirement answers NOT_ACCEPTED for six backends — the four PKCS#11 tokens and both Google tokens — while keyIdRequirement answers NOT_ACCEPTED for four. A client that derives one from the other would stop asking a Google deployment for the resource path that is its only coordinate.

Common Causes

  • A PKCS#11 backend (softhsm, nshield, luna, cloudhsm) submitted with a key label. The label left in the form after switching the declared backend away from a Cloud KMS token is the usual route in.
  • A Cloud KMS backend submitted with no keyId — the key ARN, resource path, vault key name or Managed HSM key name is the one coordinate that names the key on those families.

Response Example

{
  "type": "https://docs.ankatech.co/errors/deployment-backend-key-id-requirement",
  "title": "Backend Key Coordinate Requirement Not Satisfied",
  "status": 422,
  "detail": "The declared key-protection backend does not accept a key coordinate; the platform derives the key name itself.",
  "instance": "/api/v3/admin/platform/setup/backend/configuration",
  "timestamp": 1787494020,
  "extensions": {
    "field": "keyId",
    "requestId": "0c7d3e91-42b8-4f5a-8e63-1d9a7c05b2f4"
  }
}

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

How to Resolve

  1. Read detail. It states which half of the requirement was violated — a required coordinate that is absent, or a coordinate supplied to a backend that accepts none. There are exactly two fixed strings and neither varies with the deployment.
  2. Read extensions.field, which is always keyId.
  3. Supply the coordinate, or remove it, and resubmit. If the coordinate was right and the backend token was wrong, correct the token instead.
  4. On a PKCS#11 token there is normally nothing to resubmit at all. That family accepts no endpoint, accepts no key coordinate and seals no deployment credential — the conjunction of three that makes a declaration self-completing, and the reason this is true of the four PKCS#11 tokens rather than of the six that accept no endpoint. Its declaration is already complete: the platform writes the descriptor at POST /api/v3/admin/platform/setup/backend/declare and the next step is POST /api/v3/admin/platform/setup/backend/activate. Reaching this refusal there means a form sent a coordinate the surface does not ask for.

The refusal names the case; it never names the value. No coordinate, ARN, resource path, key label, Azure account URL, project or credential fragment appears in detail, in the extensions, or in the server-side log line.

A persisted coordinate on a token that accepts none is inert, not fatal. A row written before this requirement existed is simply ignored on the read path for a backend whose declared requirement is NOT_ACCEPTED — the platform derives the key's name itself either way. It is not resurrected, it is not used as a label, and it does not need to be cleaned up before an activation can succeed.

Where it is raised

  • PUT /api/v3/admin/platform/setup/backend/configuration — the deployment plane's write
  • POST /api/v3/admin/platform/setup/backend/validate — the deployment plane's rehearsal, which runs the same requirement check from the same single reader