Skip to content

Key-Material Backend Bind Verification Failed

URI: https://docs.ankatech.co/errors/tenant-backend-bind-selftest-failed
HTTP Status: 422 Unprocessable Content

When you see this

The per-tenant BYOK bind runs an ephemeral wrap/unwrap round trip against the tenant's declared key-material backend before it marks the backend active. This type means the backend answered, and its answer does not change by waiting: it refused the credential or the operation, returned different bytes, or reported that the declared key, the declaration or the security domain cannot be used. The bind does not advance to active; the declaration reverts to pending-bind. The response carries no Retry-After header, because binding the same declaration again gets the same answer.

The reason extension member names what the backend answered, and the detail names it too:

reason What the backend answered What to correct
AUTHENTICATION_REFUSED It did not accept the stored credential: an access key it does not recognise, a secret that does not match, an expired token, a service-account key or client secret it rejects The credential
REFUSED It accepted the credential and declined the operation — the credential lacks encrypt or decrypt on the declared key The key policy or role assignment at the provider
ROUND_TRIP_MISMATCH The unwrap did not return the bytes the wrap consumed Escalate — the key is not reversible as declared
KEY_ABSENT The declared key does not exist. On Google Cloud KMS this is also the answer for a project the credential cannot see The declared key, or a credential from the account, project or directory that owns it
DESCRIPTOR_INVALID The declaration cannot produce a client — a malformed coordinate The declaration
SECURITY_DOMAIN_ABSENT The declared security domain is not present The declaration

A backend that could not be reached in time, or that asked the platform to slow down (THROTTLED), is not this type: it is Key-Material Backend Bind Verification Unavailable (503, with Retry-After). A verification the platform could not route at all is Upstream Service Unavailable (502), naming core-api by role: on this plane core-api builds the tenant's backend client, so the routing failure is its condition. The same 422 status is also answered, with a different type, when the declared backend is not admissible on the deployment.

Only the bind raises this type. A credential rotation is verified by its own check and refuses a new credential with BYOK Credential Self-Test Failed (422), BYOK Declared Key Unusable (422) or BYOK Credential Self-Test Unavailable (503). The two operations classify the backend's answer the same way.

The probe is deliberately ephemeral and non-tenant: it creates no key material and never makes the tenant's key-material-exists read true, so a tenant that fails this check can still change its declared backend.

Response Example

{
  "type": "https://docs.ankatech.co/errors/tenant-backend-bind-selftest-failed",
  "title": "Key-Material Backend Bind Verification Failed",
  "status": 422,
  "detail": "The declared key-material backend answered the bind verification and refused it (reason KEY_ABSENT). Waiting will not change the answer. Correct the declared key, or the account, project or directory the credential belongs to, then bind again. The backend was not bound.",
  "instance": "/api/v3/admin/tenants/9f1c0b52-6a3d-4f8e-9b21-7c5d4e3a1b09/key-backend/byok/bind",
  "extensions": {
    "requestId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "reason": "KEY_ABSENT"
  }
}

Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. The body never names the key, the endpoint, the account or any credential field.

How to Resolve

  1. Read reason against the table above.
  2. For AUTHENTICATION_REFUSED, replace the credential with PATCH /api/v3/admin/tenants/{tenantId}/key-backend/byok/credential — the new one is checked against the declared key before it is stored, so a second wrong credential is refused there.
  3. For KEY_ABSENT, DESCRIPTOR_INVALID or SECURITY_DOMAIN_ABSENT, correct the declaration; for REFUSED, grant the credential encrypt and decrypt on the declared key at the provider.
  4. Bind again. The declaration is still pending-bind, so nothing has to be unwound first.

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