Key Operation Incompatible
URI: https://docs.ankatech.co/errors/key-operation-incompatible
HTTP Status: 400 Bad Request
When you see this
A re-encryption or a re-sign named two keys of different classes: one of them is symmetric and the other is asymmetric. Re-encrypt and re-sign move a payload from one key to another key of the same class, so a symmetric ↔ asymmetric pair is refused in both directions.
A composite (hybrid) key is asymmetric. A symmetric key paired with a SIMPLE asymmetric key or with a composite key is therefore refused the same way.
Core API returns this problem on four operations:
| Operation | detail |
|---|---|
POST /api/v3/crypto/reencrypt | Unsupported re-encryption: symmetric <--> asymmetric keys are not permitted |
POST /api/v3/crypto/stream/reencrypt | Unsupported re-encryption: symmetric <--> asymmetric keys are not permitted |
POST /api/v3/crypto/resign | Unsupported re-sign: symmetric <--> asymmetric keys are not permitted |
POST /api/v3/crypto/stream/resign | Unsupported re-sign: symmetric <--> asymmetric keys are not permitted |
The detail names the two classes and no key. Identify the problem by its type (RFC 9457 §3.1.1), never by parsing detail (RFC 9457 §3.1.4).
The rule applies to a token addressed to or signed by one key, and to the one multi-key re-encryption it can still reach (a symmetric source recipient whose header declares an asymmetric alg, replaced by a SIMPLE asymmetric key). Every other symmetric key in a token addressed to or signed by several keys — an entry, newKid or a kept recipient or signer — is 422 unprocessable-entity with extensions.errorCode JOSE_SYMMETRIC_ACTOR, not this 400.
Common Causes
- A symmetric source re-encrypted to an asymmetric key, or the reverse. The source key is the one the token's protected header names (
kidandank_kv, orsourceKid); the target isnewKid. - A symmetric source re-signed with an asymmetric key, or the reverse. An HMAC signature cannot become an ECDSA, EdDSA, ML-DSA or composite signature by re-signing, and none of those can become an HMAC.
- A composite key on one side and a symmetric key on the other. A composite key counts as asymmetric.
When it is decided
Every check below that applies to the request answers first; the key-class rule is decided after them, and before any key material is unwrapped or any byte of the file part is read:
- Authentication (
401), the operation's scope (403) and the licence (402). - Request shape and source-key selection. In a token addressed to or signed by several keys, a recipient or signer whose
algis symmetric or direct is refused here with422JOSE_SYMMETRIC_ACTOR, before any grant is checked. On/stream/resign, avalidityDaysoutside its bounds is400invalid-input. - Capability Grant (
403) and key lifecycle (403). - On
/resignand/stream/resign: asourceKidsupplied for a composite source is400invalid-input; an unresolved or required-but-unavailable timestamping policy is503; and on/resign, aCOMPACTserialization requested under a mandated timestamp is400invalid-input. - Key capability and
keyOps(404, or400invalid-inputfor an operation the key does not support) — on every route, including the buffered re-encryption of one recipient of a JWE addressed to several keys. - The existing
422unprocessable-entityrefusals, which keep precedence over the key-class rule:- in a token addressed to or signed by several keys, a composite recipient is
JWE_COMPOSITE_RECIPIENT, and a symmetricnewKidor kept recipient or signer isJOSE_SYMMETRIC_ACTOR. On a re-encryption of a JWE addressed to several keys these recipient checks are decided right after step 3, before the capability check of step 5; - on re-encryption, a JWE whose
algsits only in the unprotected recipient header isJWE_ALG_NOT_PROTECTEDfor a symmetric or composite key, andJWE_ALG_KEY_MISMATCHwhen thatalgis not the key's own key-management algorithm. On the buffered re-encryption of one recipient of a JWE addressed to several keys this check is also decided before step 5.
- in a token addressed to or signed by several keys, a composite recipient is
- The key-class rule:
400key-operation-incompatible.
On the streaming routes the refusal arrives before the response body starts, so there is no body part and no StreamVerdict.
Response Example
{
"type": "https://docs.ankatech.co/errors/key-operation-incompatible",
"title": "Key Operation Incompatible",
"status": 400,
"detail": "Unsupported re-encryption: symmetric <--> asymmetric keys are not permitted",
"instance": "/api/v3/crypto/reencrypt",
"correlationId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"timestamp": 1736936400,
"extensions": null
}
Content-Type: application/problem+json — the response follows RFC 9457 Problem Details. correlationId is a top-level member, timestamp is in epoch seconds, and this problem carries no extension member, so extensions is null.
How to Resolve
- Re-encrypt or re-sign to a key of the same class as the source: symmetric to symmetric, or asymmetric (SIMPLE or composite) to asymmetric.
- To move a payload from a symmetric key to an asymmetric one, or the reverse, decrypt (or verify) it with the source key and then encrypt (or sign) it with the target key as two separate operations. This is not a re-encryption: it needs a
DECRYPT(orVERIFY) grant on the source key and anENCRYPT(orSIGN) grant on the target, and the plaintext reaches the caller in between. - Read the key's metadata (
GETthe key) to confirm itsktybefore re-submitting:octis symmetric.
For full schema definitions, examples, and interactive testing, see the Developer Hub Reference.