808bits

CKR_CRYPTOKI_NOT_INITIALIZED

PKCS#11 return value · 0x00000190 · decimal 400
hex 0x00000190 decimal 400 name CKR_CRYPTOKI_NOT_INITIALIZED

A PKCS#11 library holds its state per process, and that state has to be set up before anything else and torn down exactly once at the end. Both halves of that are hard to guarantee in a process where more than one component loads the same module, and this code is what you get when the guarantee fails. The version of it that is genuinely a missing call is the easy one.

What the token is reporting

The library has not been initialized in this process, or it was and something has since finalized it. Every other call requires that state to exist.

Likely causes

Ordered by how often they turn out to be the answer. That ordering is a judgement from experience, not a measured frequency.

Initialization never happened

The straightforward case, most often in a code path that was reached before setup, or in a test that exercises one function in isolation.

Check it: Confirm the initialization call runs before the failing one. If setup is lazy, check whether the lazy path is reached at all on this route through the code.

Another component finalized the shared library

Two components in one process, each loading the same module, each believing it owns the lifecycle. The one that shuts down first tears down the state the other is still using, and the failure lands in code that did nothing wrong.

Check it: Search the whole process for a finalize call, dependencies included. If a framework or a language binding manages PKCS#11 for you, assume it finalizes at some point unless it documents otherwise.

A fork, where the child inherited nothing usable

The library’s state does not survive a fork in any meaningful way. Some libraries detect the process change and report this. Others report an invalid session handle instead, which is the same underlying problem described differently.

Check it: Compare the process id at initialization with the process id at the failing call. Any difference explains everything without further investigation.

Fix: Initialize after forking, in the child that will use the token. Never before.

Initialization failed and its return code was not checked

If setup failed for a configuration reason, every later call reports uninitialized state, and the message that would have explained why was thrown away at the first call.

Check it: Check the return code of the initialization call itself. This is the code whose failure most often goes unchecked, and its message is far more useful than anything downstream.

Which calls return it

C_GetSlotList, C_OpenSession, C_Login, C_Sign

Often confused with

  • CKR_SESSION_HANDLE_INVALID: The other side of the same coin after a fork or a finalize. Which of the two you see is a property of the library, not of your mistake.

See also

  • CKR_CRYPTOKI_ALREADY_INITIALIZED

Sources

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.