808bits

CKR_ATTRIBUTE_TYPE_INVALID

PKCS#11 return value · 0x00000012 · decimal 18
hex 0x00000012 decimal 18 name CKR_ATTRIBUTE_TYPE_INVALID

Each object class carries its own list of attributes, and asking for one outside that list is the textbook trigger. In practice the code turns up far more often from a library that simply never stored the attribute you asked for, which the specification also permits, so the same request can succeed on one token and fail on the next. The result you discarded may have been mostly filled in.

What the token is reporting

An attribute type in your template is not one this object has. A library may return it because the attribute is not defined for that class, or because this particular library does not keep it. The length field of the offending entry is set to CK_UNAVAILABLE_INFORMATION and the other entries may still have been filled.

Likely causes

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

A field that belongs to a different key type

CKA_MODULUS on an EC key, CKA_EC_POINT on an RSA key, CKA_VALUE_LEN on a key pair. Code that handles one key type and is later pointed at another does this on its first read. A find by label with no class in the template makes it worse, because the handle you got back may be the certificate rather than the key.

Check it: Read CKA_CLASS and CKA_KEY_TYPE on the handle before anything else, and compare with what your code assumed.

An attribute the specification defines and this library does not store

Libraries that rebuild objects from a card’s own file format, or from a network HSM’s object store, only carry the attributes that format has. Dates, subjects and the less common key flags are the usual casualties. The specification allows the library to answer with this code, so the failure is legitimate and portable code has to tolerate it.

Check it: Request the attributes one at a time. The missing one comes back with a length of CK_UNAVAILABLE_INFORMATION, which prints as -1 or as the largest unsigned value depending on your language.

Fix: Treat an unavailable length as “absent” rather than as a failed call, and keep the values of the other entries.

One entry in a long template failed and the whole result was thrown away

C_GetAttributeValue walks the whole template and reports this code if any entry was missing, while still filling in every entry it could. Object dumpers and inventory scripts read twenty attributes at once and discard all of them on a non-zero return, which turns one absent attribute into an object that “cannot be read”.

Check it: Look at the per-entry length fields after the call rather than only at the return code.

Fix: Check each ulValueLen and skip the unavailable ones, or read in two passes: the attributes every object has, then the optional ones.

A vendor attribute compiled against the wrong header

Vendor attributes live above CKA_VENDOR_DEFINED and two vendors can assign the same number to different things. A constant from one SDK’s header used against another vendor’s library is unknown to it, or worse, means something else.

Check it: Check the numeric value of the attribute against the header of the library you are actually loading.

Which calls return it

C_GetAttributeValue, C_SetAttributeValue, C_CreateObject, C_FindObjectsInit, C_GenerateKeyPair

What it is not

It is not a wrong value. The value was never looked at, and a value the token rejects is CKR_ATTRIBUTE_VALUE_INVALID. It is also not a permission problem: an attribute you may not read comes back as sensitive.

Often confused with

  • CKR_ATTRIBUTE_VALUE_INVALID: The next check along. Type invalid means the attribute is unknown here, value invalid means it is known and what you set is not acceptable.
  • CKR_ATTRIBUTE_SENSITIVE: Both are reported by the same read, and when a template contains one unknown and one sensitive attribute the library picks which to report.
  • CKR_TEMPLATE_INCOMPLETE: The mirror image on creation: an attribute the class requires is missing, rather than one it does not know being present.

See also

By library

SoftHSMv2

When one template contains a sensitive attribute and an unknown one, the sensitive code wins, then this one, then buffer too small (P11Objec ts.cpp). So this code from SoftHSM also tells you nothing in the template was sensitive.

OpenSC

On a private key the library returns this for anything outside its own switch, while CKA_SUBJECT, CKA_START_DATE and CKA_END_DATE come back with a zero length and CKR_OK instead ([framework-pkcs15.c](http s://github.com/OpenSC/OpenSC/blob/4fab8b57301f035432191d582922d95d7d426 802/src/pkcs11/framework-pkcs15.c#L4227-L4241)). Absent-with-success and absent-with-error both exist in the same library, so a dumper has to handle both.

YubiHSM 2

Each object type has a fixed attribute list in the library and anything else is answered with this code, including attributes a fuller library would synthesize (util_pkcs11.c).

Thales Luna

Two native return codes map to it, one for an attribute that is not found on the object and one for an attribute type the firmware does not recognise at all. The client log carries the native code, which is how you tell the two apart.

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.