Upstream Rejected Request
URI: https://docs.ankatech.co/errors/upstream-rejected-request
HTTP Status: 400, 404, 409 or 422 — whichever status the upstream service returned
When you see this
The Admin API called an internal service on your behalf, that service refused the request, and its refusal could not be safely re-presented as its own. So the Admin API answered with its own type, its own title and its own sentence, carrying forward only the status.
This is the degenerate branch of the relay contract. The relay is described in full on S2S Relay Envelope; this page documents the type it emits when the upstream body is unusable.
Why the upstream body was not relayed
The type member is a classifier — the console and the published clients branch on it — so relaying an arbitrary upstream value would be a classification-forgery vector. A type is carried through only when it is a member of the https://docs.ankatech.co/errors/ registry. Everything else lands here:
- the upstream response is not a
problem+jsondocument at all; - it is one, but its
typeis absent, relative,http:, a non-registryhttpsorigin, or a look-alike authority; - its
detailis absent, blank, or reduced to nothing once control characters are stripped.
Only the statuses 400, 404, 409 and 422 are re-presented as a client fault at all. Every other upstream status — 401 and 403 included, which mean the upstream refused the Admin API's own service credential and say nothing about your request — becomes a 502 naming the upstream by role.
The keystore-import variant
A keystore import whose entries all failed returns this same type with a counting sentence instead of the generic one, because that response really does carry structure — the per-entry projection under extensions.failedEntries. Saying "returned no usable problem description" there would deny the data in the same body. The member and its bounded shape are documented on Unprocessable Entity.
Response Example
{
"type": "https://docs.ankatech.co/errors/upstream-rejected-request",
"title": "Upstream Rejected Request",
"status": 422,
"detail": "The key-management service rejected the request and returned no usable problem description.",
"instance": "/api/v3/admin/tenants/2f1c9d84-6b2e-4d3a-9f57-0a1b2c3d4e5f/keys/my-mlkem-key/rotate",
"timestamp": 1730000000,
"extensions": {
"requestId": "550e8400-e29b-41d4-a716-446655440000"
}
}
Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. This is an Admin API body, so the correlation identifier is extensions.requestId; see Error Index & Overview.
How to Resolve
- Read
status. It is the upstream's status and it still classifies the failure:400and422mean the request needs correcting,404that the resource is not there,409that the state conflicts. - On a keystore import, read
extensions.failedEntries— the per-entry reasons are there even though the sentence is generic. - Quote
extensions.requestIdwhen you contact support. The upstream's own diagnosis is in the server log against that correlation identifier; it is deliberately absent from the response. - Retrying without changing anything reproduces the same refusal. This is not a transient availability failure — that one is 502.
For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.