Skip to content

Misdirected Request

URI: https://docs.ankatech.co/errors/misdirected-request
HTTP Status: 421 Misdirected Request

When you see this

The cryptographic API runs as more than one deployment role, and each role serves part of the API: one serves the streaming operations (/api/v3/crypto/stream/, /api/v3/migration/stream/, /api/v3/interoperability/ and the PKCS#7 conversions), the other serves everything else. Your request reached a role that does not serve its route, so that role refused it without processing it.

The ANKASecure edge sends every request to the role that serves it, so a request that goes through the platform's public address does not receive this status. You see it only when a request reaches a role directly, without passing through that routing, or when the routing of a deployment disagrees with the roles it runs — both are deployment conditions, not a defect in your request.

This is the meaning RFC 9110 gives the status: the request "was directed at a server that is unable or unwilling to produce an authoritative response for the target URI" (RFC 9110 §15.5.20). RFC 9110 defines it for a target the server is not configured for; ANKASecure applies it to a route the receiving process does not serve.

What was and was not done

The refusal happens before the operation starts:

  • No handler ran, so nothing was encrypted, signed, imported or changed.
  • No usage was counted and no cryptographic audit event was recorded — the request is not a cryptographic operation.
  • No request body was read for processing: no file was spooled, and no streaming slot was taken.

Authentication still comes first. A request without a valid token receives 401 Unauthorized, not this status — except an OPTIONS request that is not a CORS preflight, which the platform admits without a token and therefore answers with this status when it reaches the wrong role. A request with a valid token receives this status even when the token lacks the scope the operation requires: scope checks run only where the operation is served.

Within a role's own part of the API, an unknown path is still 404 Not Found. A path in the other role's part is 421 whether or not an operation exists at that path. The part a path belongs to is decided by its route prefix, compared without regard to letter case, so a misspelled path — a trailing slash, different capitalisation — is 404 on one role and 421 on the other. A path with a doubled slash is refused with 400 Bad Request before the role is considered.

Every Core API operation under /api/v3/ lists this 421 response in the published API reference.

Response Example

{
  "type": "https://docs.ankatech.co/errors/misdirected-request",
  "title": "Misdirected Request",
  "status": 421,
  "detail": "This route is not served by the deployment role that received the request.",
  "instance": "/api/v3/crypto/stream/encrypt",
  "correlationId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "timestamp": 1745119200
}

Content-Type: application/problem+json — the response follows RFC 9457 Problem Details, with correlationId and timestamp (Unix epoch seconds) at the top level as on every Core API error. The response names no host, alias or service, and carries no Retry-After header: waiting does not change which role a route belongs to.

Large request bodies: you may see a closed connection instead

The role refuses without reading your body, but the bytes you already sent still have to be accounted for on the connection:

  • Over HTTP/1.1 the server discards a bounded remainder of the refused body — up to its configured max-swallow-size, 2 MiB by default — and then closes the connection. Tomcat discards that remainder because "if Tomcat does not swallow the body the client is unlikely to see the response" (Tomcat HTTP connector — maxSwallowSize). A client that sends a body larger than that bound, for example a multi-gigabyte streaming upload, may therefore see the connection close or reset instead of the 421 response.
  • Over HTTP/2 the server ends the response and resets the request stream, so it accepts at most one stream flow-control window of further body and the connection stays open for other requests.

Either way the request was not processed. Treat a reset during a large upload sent directly to a role like the 421 it stands in for.

How to Resolve

  1. Send the request through the platform's public API address rather than to an internal service address. The edge routes each request to the role that serves it.
  2. If the request already goes through the platform's address, the deployment's routing disagrees with its roles. Report it to the platform operator with the correlationId: it identifies the refusal in the server-side logs and metrics.

A retry over the same path is safe — nothing was committed — but a retry that reaches the same role receives the same 421. RFC 9110 permits a retry "over a different connection"; for ANKASecure, the connection that matters is the one through the edge.

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