CKR_MECHANISM_INVALID
Every PKCS#11 library ships knowing a set of mechanisms, every token exposes its own subset of those, and the header on your build machine knows a third set that may match neither. This code appears when those three disagree. Nothing about it is subtle, but the fix is almost never in the calling code, which is why it can take a surprisingly long time.
What the token is reporting
Either the library has never heard of the mechanism you named, or it knows it and does not accept it for the operation you tried to use it in. The two cases are not distinguished, so both are worth checking.Likely causes
Ordered by how often they turn out to be the answer. That ordering is a judgement from experience, not a measured frequency.
The token does not expose it, even though the header defines it
A header defines every constant the vendor has ever shipped. A token exposes what its firmware, its licence and its current policy allow. Compiling successfully against a constant proves nothing at all about whether the device will accept it.Check it: Ask the slot for its mechanism list and check whether your value is in it. This is the whole diagnosis in one call, and it is worth doing before anything else.
The mechanism is known but not valid for that operation
Mechanisms carry flags for the operations they support. Using a derivation mechanism to sign, or a key generation mechanism to encrypt, is a well-formed call that the library will refuse. Some libraries return a general failure here instead, which is why the same mistake produces different codes on different vendors.Check it: Read the mechanism’s flags for that slot and compare them against the operation. A mechanism that lists only derive will never sign, no matter what key you hand it.
It is a vendor-defined value and you are on a different vendor
Anything at or above the vendor-defined boundary means whatever the library that defines it says it means, and nothing at all anywhere else. Code that hard-codes such a value works on one vendor’s library and fails on every other.Check it: Check whether the value is in the vendor range. If it is, the question is not what the mechanism does but which library you are actually talking to.
The token is in a mode that hides it
A token in an approved or restricted mode presents a shorter mechanism list than the same token unrestricted. Nothing is broken, and the same code on the same hardware works in one configuration and not in another.Check it: Compare the mechanism list against a token in the other mode, or against the vendor’s documentation for what that mode removes.
Which calls return it
C_SignInit, C_EncryptInit, C_DeriveKey, C_WrapKey, C_GenerateKeyPair
What it is not
It is not usually a typo. The constant compiled, so it exists somewhere. The question is whether it exists on the token you are talking to right now.Often confused with
CKR_MECHANISM_PARAM_INVALID: The mechanism is accepted and the parameter structure attached to it is not. That is a much narrower problem and points straight at the parameters rather than at the mechanism.CKR_FUNCTION_FAILED: What some libraries return instead when a known mechanism cannot be used for the operation, so the two overlap in practice.
By library
Thales ProtectServer
This library exposes 265 mechanisms on the software-only token, and 86 of them are vendor-defined. A value from that range is meaningless on any other vendor’s library, so it is worth checking which side of the boundary a failing mechanism falls on before looking anywhere else.SoftHSMv2
The list a SoftHSMv2 slot exposes is a fixed table of 112 names filtered twice, once by what the crypto backend was built with and once by theslots.mechanisms line in softhsm2.conf, which can name a positive list or subtract from the full one ([SoftHSM.cpp](https://g ithub.com/softhsm/SoftHSMv2/blob/884cb38f3d2012a0447bd5f50dbd29c429987 c41/src/lib/SoftHSM.cpp#L928-L967)). A mechanism that is in the header and not in the list gets this code, and the cause may be a configuration file on the test machine rather than anything in the build. The list from a fresh build is on the implementation page.Sources
- PKCS #11 Specification Version 3.2, OASIS. Read 2026-09-10. Used for constant name and numeric value.
Every description, cause and check on this page is written from scratch. The specification is cited for the constant's name and its number, which are facts, and for nothing else.