808bits

PKCS#11 by library

4 libraries

A return value means what the library that returned it says it means, and above 0x80000000 the specification says nothing at all. One page per library, each marked with where its facts came from: the vendor’s published documentation, a live token read with a probe that never logs in, or the library’s own source at a pinned commit.

  • OpenSC · The one switch that turns 84 smart card errors into PKCS#11 return values, what falls through it, and what pkcs11-tool prints. read from source
  • SoftHSMv2 · Where SoftHSMv2 sends CKR_GENERAL_ERROR, why slot 0 disappears after the first token, and the 103 mechanisms a fresh build exposes. read from source and observed, 103 mechanisms observed
  • Thales Luna · Luna's vendor-defined PKCS#11 constants, and the BIP32 error codes that carry the same names as ProtectServer's at different values. documented
  • Thales ProtectServer · The vendor-defined CKR constants Thales documents for ProtectToolkit-C, the mechanism list read off the 7.3 software token, and what changed since 5.9. documented and observed, 66 return values, 279 mechanisms observed

Same name, different number

A constant name is not an identifier. Two libraries, or a library and the specification, can agree on the spelling and disagree on the value, and a lookup in the wrong table then returns a confident wrong answer. Every case found so far is below.

BIP32 error codes

Luna and ProtectServer both put BIP32 derivation inside the HSM and both document the same five error codes for it. The values do not match. They are offset by eight, in the same order, which reads like two teams numbering the same list against different starting points rather than a deliberate choice. The specification has no BIP32 codes at all.
ConstantPKCS#11 3.2LunaProtectServer
CKR_BIP32_CHILD_INDEX_INVALID-0x800000830x8000007B
CKR_BIP32_INVALID_HARDENED_DERIVATION-0x800000840x8000007C
CKR_BIP32_MASTER_SEED_LEN_INVALID-0x800000850x8000007D
CKR_BIP32_MASTER_SEED_INVALID-0x800000860x8000007E
CKR_BIP32_INVALID_KEY_PATH_LEN-0x800000870x8000007F

Token not initialised

ProtectServer has documented a private CKR_TOKEN_NOT_INITIALIZED for years. Version 3.2 of the specification, an OASIS Standard since June 2026, added a constant with the same name in the base range. A ProtectToolkit build that adopts the 3.2 header will have two constants with one name, and code that switches on the name will compile against whichever header came first on the include path.
ConstantPKCS#11 3.2LunaProtectServer
CKR_TOKEN_NOT_INITIALIZED0x00000208-0x80000116