Skip to content

Backend Endpoint Requirement Not Satisfied

URI: https://docs.ankatech.co/errors/byok-endpoint-requirement
HTTP Status: 422 Unprocessable Entity

When you see this

The endpoint you submitted does not satisfy the declared backend's own requirement: the backend requires a connection endpoint and none was supplied, it accepts none and one was, or — on a tenant's own backend — the endpoint is not a host of the backend's vendor. The request was refused before anything was written and before anything was contacted — no declaration was recorded, no coordinates were stored, and no outbound connection was opened.

Only the pre-commit checks answer this type. The validate operations (POST …/validate) answer all three cases with it. A declaration (PUT …/driver-declaration) answers none of them with it: its descriptor check refuses each first with 400 key-backend-declaration-invalid, extensions.member: "properties" and field: "endpoint" — reason UNKNOWN for an endpoint sent to a backend that accepts none, MISSING for a required one left out, and ENDPOINT_REFUSED for an endpoint outside the vendor's suffixes on the tenant BYOK plane.

The body is syntactically valid. The backend token is one of the nine, and the endpoint, when present, is a well-formed HTTPS URL. What the platform refuses is the pair: this backend, with an endpoint, or this backend, without one.

The requirement is a property of the backend family, declared once beside the platform's backend vocabulary and read by one component:

Declared backend endpoint What it is
azure-kv required the vault URL (https://<name>.vault.azure.net/) the key name is resolved inside
azure-kv-mhsm required the Managed HSM URL (https://<name>.managedhsm.azure.net/) the key name is resolved inside — a different Azure resource type on a different host family, so a vault URL is not interchangeable here
aws-kms optional an egress pin; when supplied it is the address the platform dials
gcp-kms, gcp-kms-hsm not accepted the resource path in keyId already names the location
softhsm, nshield, luna, cloudhsm not accepted the token is reached through the deployment's own PKCS#11 library

A backend that does not accept an endpoint is refused for supplying one rather than ignoring it. An accepted-and-discarded field is a contract the platform does not honour.

The vendor domain (tenant BYOK only)

A tenant's own backend sends wrapped key material to the endpoint it declares, so on the per-tenant BYOK write and its rehearsal an endpoint must also be a host of the backend's vendor: its host must end, at a DNS label boundary, in one of the suffixes the operator admits for that vendor. The rehearsal answers a host outside them with this type; the write answers it with 400 key-backend-declaration-invalid, reason ENDPOINT_REFUSED.

Vendor Setting Default suffixes
AWS (aws-kms) ankasecure.key-protection.byok.endpoint-suffixes.aws .amazonaws.com, .amazonaws.com.cn, .amazonaws.eu
Azure (azure-kv, azure-kv-mhsm) ankasecure.key-protection.byok.endpoint-suffixes.azure .vault.azure.net, .managedhsm.azure.net, .vault.azure.cn, .managedhsm.azure.cn, .vault.usgovcloudapi.net, .managedhsm.usgovcloudapi.net

The match is on whole labels, case-insensitive, with one trailing root dot ignored and a port or path allowed: https://kms.eu-west-1.amazonaws.com and a VPC endpoint https://vpce-0a1b2c3d.kms.eu-west-1.vpce.amazonaws.com are admitted; https://kms.example.org, https://evil-amazonaws.com, https://amazonaws.com.evil.io and the bare https://amazonaws.com are refused. The host must be an ASCII DNS name (an internationalised name in its xn-- form); an IP literal or user-info is refused.

The list in force is published on the per-tenant BYOK read as coordinateContract.admittedEndpointSuffixes, so a client checks an endpoint before it submits it. It is null where the vendor domain is not checked: a backend that takes no endpoint, and the deployment plane, whose operator owns both the endpoint and the list (the managed-tier planes are not checked either). Narrowing a list refuses new declarations only; it never unbinds a backend a tenant already declared.

Common Causes

  • An Azure Key Vault or Managed HSM backend declared without its account URL — the vault URL for the first, the Managed HSM URL for the second.
  • An Azure account URL left in the form after switching the declared backend to a Cloud KMS or PKCS#11 token that accepts none.
  • A Google Cloud KMS backend given an endpoint. The location is a segment of the resource path in keyId; there is no separate host to name.
  • A PKCS#11 backend given a host. The token is reached through the deployment's PKCS#11 library, not over a network address the caller supplies.
  • A tenant's AWS KMS or Azure endpoint on a host outside the vendor's suffixes — a proxy, a private DNS name, or a sovereign cloud whose suffix the operator has not added.

How to Resolve

  1. Read detail. It states which part of the requirement was violated — a required endpoint that is absent, an endpoint supplied to a backend that accepts none, or an endpoint that is not a host of the backend's vendor.
  2. Read extensions.field, which is always endpoint.
  3. Supply the endpoint, remove it, or point it at a vendor host, and resubmit. If the endpoint was right and the backend token was wrong, correct the token instead. If a legitimate vendor host is refused (a sovereign cloud, for example), the operator adds its suffix to the vendor's setting.

The refusal names the case; it never names the value. No endpoint, host, region, resource path, project, ARN, Azure account URL or credential fragment appears in detail, in the extensions, or in the server-side log line. Naming which part was violated discloses nothing the caller did not send, and withholding it would make a published contract undiagnosable.

The pre-commit check refuses what the commit refuses, without writing. An endpoint the POST .../validate rehearsals below refuse with this type is refused by the declaration too, with the descriptor check's 400 key-backend-declaration-invalid naming properties and endpoint. Unlike a coordinate that fails its grammar (an HTTP 200 carrying a FAILED verdict), an unsatisfied endpoint requirement is a 422 on the rehearsal: the question cannot be answered for a pair the platform will not admit.

Where it is raised

  • POST /api/v3/admin/platform/setup/backend/validate — the deployment plane's rehearsal
  • POST /api/v3/admin/tenants/{tenantId}/key-backend/byok/validate and its platform-plane twin — the per-tenant rehearsal
  • POST /api/v3/admin/platform/key-backend/tiers/{tier}/validate — the managed-tier rehearsal