Skip to content

Compliance Pack Not Licensed

URI: https://docs.ankatech.co/errors/compliance-pack-not-licensed
HTTP Status: 403 Forbidden

When you see this

A request asked for a live evaluation, a remediation write or an evidence export of a compliance pack that is in the running release's catalogue but that the deployment licence does not entitle: the pack is locked. The Admin API answers it on these nine operations:

operationId Request
getCompliancePackEvaluation GET /api/v3/admin/tenants/{tenantId}/compliance-evaluations/{packId}
getPlatformCompliancePackEvaluation GET /api/v3/admin/platform/compliance-evaluations/{packId}
getPlatformTenantCompliancePackEvaluation GET /api/v3/admin/platform/compliance-evaluations/{packId}/tenants/{tenantId}
updateComplianceRemediationAction PATCH /api/v3/admin/tenants/{tenantId}/compliance-remediation/{packId}/actions/{actionKey}
previewComplianceRemediationAction GET /api/v3/admin/tenants/{tenantId}/compliance-remediation/{packId}/actions/{actionKey}/preview
executeComplianceRemediationAction POST /api/v3/admin/tenants/{tenantId}/compliance-remediation/{packId}/actions/{actionKey}/executions
createComplianceAttestation POST /api/v3/admin/tenants/{tenantId}/compliance-remediation/{packId}/attestations
exportComplianceEvidence GET /api/v3/admin/tenants/{tenantId}/compliance-evidence/{packId}
exportComplianceEvidencePackage GET /api/v3/admin/tenants/{tenantId}/compliance-evidence/{packId}/package

It is decided last: another tenant's path (404), a malformed identifier (400), a missing scope (403 Forbidden) and an identifier that names no pack of this release (404 Compliance Pack Not Found) are all answered before the licence is read. A refused request writes nothing, emits no audit event, calls no other service and signs nothing.

One exception comes before the licence: executeComplianceRemediationAction retried with the Idempotency-Key and request of an execution already recorded answers that execution's stored result, even after the pack left the licence, because a replay writes, emits and calls nothing.

It is a 403, not a 404, because the pack exists and its stored records stay readable; no permission the caller could be granted changes the answer, so a client tells it from a missing scope by the type, not by the status. The pack's stored records never answer it: its history on both planes, its remediation plan, its executions and its attestations answer 200 with licensing: NOT_LICENSED, and the evidence verification keys are served on every licence status.

Common Causes

  • The licence was issued, or renewed, without this pack. The packs it names are the ones the platform evaluates; every other pack of the catalogue is locked.
  • The licence has expired. An expired licence entitles no pack, so the whole catalogue is locked. (A trial entitles every pack of the catalogue, and a licence in its grace period keeps every pack it names.)
  • The identifier was taken from the catalogue list or from lockedPacks, rather than from the evaluated packs of the evaluation list.

Response Example

{
  "type": "https://docs.ankatech.co/errors/compliance-pack-not-licensed",
  "title": "Compliance pack not licensed",
  "status": 403,
  "detail": "The requested compliance pack is not evaluated on this deployment: its licence does not include it.",
  "instance": "/api/v3/admin/tenants/6f1b2c4e-8a3d-4f7e-9c21-5b0d7e9a1f34/compliance-evaluations/NSA_CNSA_2_0",
  "timestamp": 1791216000,
  "extensions": {
    "requestId": "3b8f0d2a-61c4-4e9b-a7d5-0f2e9c41b6a8"
  }
}

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

The detail is a fixed sentence: it names no pack identifier and states no licence status. The locked packs are what the evaluation lists return in lockedPacks, not what a refusal enumerates, and no refusal states the licence status on the tenant plane.

How to Resolve

  1. List the packs with GET /api/v3/admin/tenants/{tenantId}/compliance-evaluations (or the platform-plane list) and use an identifier from evaluations; lockedPacks lists the ones the licence does not entitle.
  2. To read what was recorded while the pack was licensed, use its history, its remediation plan, its executions or its attestations: they stay readable, marked licensing: NOT_LICENSED.
  3. If the pack should be evaluated, the deployment needs a licence that names it. A platform administrator sees the licence status and its packs on the License screen; a new licence is issued with the pack and imported there. Once it is in force the pack is evaluated again from the next request. See Compliance Packs.

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