Skip to content

Payload Too Large

URI: https://docs.ankatech.co/errors/payload-too-large
HTTP Status: 413 Content Too Large (RFC 9110 §15.5.14, formerly "Payload Too Large")

When you see this

The request body is larger than the bound the platform applies to it. Nothing was read past the bound, nothing was validated and nothing was changed.

Every platform service bounds the JSON request bodies it reads. A body whose Content-Type is application/json, or a structured-syntax application/*+json type, is measured against the ceiling of the route it targets:

  • a body that declares its length (Content-Length) over the ceiling is refused before a single byte of it is read;
  • a body of unknown length (chunked, or HTTP/2 without content-length) is counted while it is read and refused on the read that crosses the ceiling.

Authentication and authorization are answered first: an unauthenticated or forbidden request receives its 401 or 403, never a 413.

Ceilings

Service JSON body ceiling Routes with their own bound
Admin API 1 MiB (1,048,576 bytes) POST /api/v3/admin/tenants/{tenantId}/keys/import-key — derived from migration.max-upload-bytes
Core API 2 MiB (2,097,152 bytes) POST /api/v3/crypto/* — derived from crypto.max-plaintext-bytes; POST /api/v3/migration/analyze-pkcs7 and POST /api/v3/migration/convert-pkcs7-to-jose — derived from migration.max-upload-bytes
License Server 256 KiB (262,144 bytes) The compliance-evidence signing operation: a CycloneDX BOM (application/vnd.cyclonedx+json) up to 16 MiB, refused above it by the operation itself
Auth API, PQC Handshake API, Audit API, and every other platform service 256 KiB (262,144 bytes) —

A derived ceiling follows the operator setting that already bounds the payload, read on every request, so raising the setting raises the body ceiling with it, without a restart:

  • crypto.max-plaintext-bytes — the wire length of an envelope carrying a plaintext of that size (see Crypto payload limits*);
  • migration.max-upload-bytes — one Base64 encoding of that many decoded bytes plus a 64 KiB allowance for the rest of the JSON document: 4 × ⌈limit ÷ 3⌉ + 65,536 bytes. At the default limit of 5,000,000 bytes that is 6,732,204 bytes. Admin API and Core API apply the same formula, so a key import is bounded identically wherever it is read.

What is not governed by these ceilings:

  • multipart uploads (the /api/v3/crypto/stream/*, /api/v3/migration/stream/*, /api/v3/interoperability/* operations and the keystore imports), which keep their own per-part and per-request limits. Where the Core API's servlet container parses the multipart body itself — POST /api/v3/migration/stream/convert-pkcs7-to-jose — that limit is 100 MB per part and 101 MB per request, and a larger body is refused with this problem before the operation runs. The other streaming operations read their bodies as they arrive and carry no such limit;
  • form posts (application/x-www-form-urlencoded), which keep the container's form limit — the Auth API token endpoint bounds its form body at 64 KiB;
  • response bodies.

The edge in front of every environment accepts request bodies up to 100 MiB; a body above that is refused by the edge itself before it reaches a service.

Response

{
  "type": "https://docs.ankatech.co/errors/payload-too-large",
  "title": "Payload Too Large",
  "status": 413,
  "detail": "Request body size exceeds the maximum allowed limit of 1048576 bytes.",
  "instance": "/api/v3/admin/platform/counterparty-types"
}

The detail names the ceiling of the route and nothing else: never the size that was sent, a tenant, a key or any value from the body. Each service adds its correlation member where it places it for every other problem it answers (see the error index).

Common Causes

  • A JSON document with an oversized member — an embedded file, a long list, a large Base64 value.
  • A compact crypto operation whose plaintext is above crypto.max-plaintext-bytes.
  • A key import or a compact PKCS#7 analysis or conversion whose decoded payload is above migration.max-upload-bytes.

How to Resolve

  1. Read the detail for the ceiling of the route you called.
  2. Reduce the request: send only the members the operation documents (each documents its own maxLength and maxItems).
  3. For large data, use the streaming form of the operation (/api/v3/crypto/stream/*, /api/v3/migration/stream/*), which has no JSON body ceiling. The SDK and the CLIs fall back to streaming automatically when a compact crypto operation answers 413.
  4. If a legitimate payload is refused by a derived ceiling, the operator raises the setting it is derived from (crypto.max-plaintext-bytes or migration.max-upload-bytes) within its documented range.
* restricted content — see higher-tier documentation