CKR_OPERATION_NOT_INITIALIZED
Multi-part operations are state on the session, and this code says the session held none of the kind you asked for. The plain case is a missing Init. The ones that get reported are an Init whose failure went unchecked, an operation the library quietly cancelled after an earlier error, and two threads taking turns on one session so that one thread's Final lands after the other's has consumed the state.
What the token is reporting
The session has no active operation of the type this call belongs to. A sign needs a sign initialisation on the same session that has not since been consumed, cancelled or replaced.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 Init failed and the code went on
The initialisation returned a mechanism, key or parameter error, the caller did not check it, and the next call found no operation. The code you are reading is then the second error, and the first one is the real one.Check it: Check the return value of the initialisation call on that session. If it was anything but success, this code is a consequence.
The operation was consumed or reset by an earlier call
A successful single-part call ends the operation, so a second sign without a second initialisation gets this code. Many failures also reset the operation: a buffer too small usually leaves it in place, but a bad data length or a failed update clears it on most libraries, and the next call reports the missing state rather than the original problem.Check it: Look at the previous return code on the same session. A failure there that is not buffer too small will have cleared the operation.
Two threads sharing a session
A session carries one active operation per kind, and libraries do not partition it per thread. Thread A initialises, thread B initialises or finishes, and thread A’s final call finds nothing or finds B’s state. The failure is intermittent and load-dependent, which is the tell.Check it: Log the session handle and thread id on every call. Any session that appears under two thread ids is the answer.
Fix: One session per thread, or a session pool with exclusive checkout.
A context-specific login with nothing pending
Logging in with the context-specific user type is only valid while an operation that requires it is in progress, on a key marked as always authenticate. Called at any other time, several libraries answer with this code from the login call itself, which is not where anyone looks for it.Check it: If the failing call is a login, check the user type and whether a signing operation was initialised on that session just before.
Which calls return it
C_Sign, C_SignUpdate, C_SignFinal, C_Encrypt, C_Decrypt, C_Digest, C_FindObjects, C_Login
What it is not
It is not the library being uninitialised, which is the cryptoki variant and fails every call. It is not a session problem either. The handle is valid, it just holds no operation.Often confused with
CKR_OPERATION_ACTIVE: The mirror image. That code means an operation is already in progress when you tried to start another. Both come from the same shared-session mistake.CKR_CRYPTOKI_NOT_INITIALIZED: The library-level version. Every call fails, not just the ones that need an operation.CKR_SESSION_HANDLE_INVALID: When the session itself is gone, the state went with it, and which of the two you see depends on which check the library runs first.
By library
SoftHSMv2
Every single-part and multi-part call checks for its operation, andC_FindObjects without a find initialisation gets the same code. A failed update resets the operation, so the call after a data length failure reports this rather than the length. The login call returns it for a context-specific login with no re-authentication pending (SoftHS M.cpp).OpenSC
One helper looks up the session’s operation for every call ([misc.c](h ttps://github.com/OpenSC/OpenSC/blob/4fab8b57301f035432191d582922d95d7d 426802/src/pkcs11/misc.c#L286-L310)), and the login call returns it for a context-specific login when nobody is logged in ([pkcs11-session.c](h ttps://github.com/OpenSC/OpenSC/blob/4fab8b57301f035432191d582922d95d7d 426802/src/pkcs11/pkcs11-session.c#L359-L362)).YubiHSM 2
Comes from the sign and verify paths, single and multi-part. The other operation families report missing state through their own checks.Thales Luna
Six native codes map to it, and they include M of N activation required and the high availability user not being initialised. On a Luna this code can mean the partition is not activated, which has nothing to do with your initialisation call. The client log has the native code.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.