808bits

CKR_SESSION_READ_ONLY

PKCS#11 return value · 0x000000B5 · decimal 181
hex 0x000000B5 decimal 181 name CKR_SESSION_READ_ONLY

Sessions come in two kinds and the difference is decided once, when you open one. Read-only sessions can use the token freely and cannot change what is stored on it. This error is the boundary being enforced, and the useful question is not how to get a writable session but whether the thing you were storing needed to be on the token at all.

What the token is reporting

The call would have modified persistent state on the token, and the session you made it through was not opened for writing.

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 session was opened without the read-write flag

The flag that makes a session writable has to be passed explicitly at open time, along with the flag that every session needs for historical reasons. Omitting it is easy, and everything except writing works afterwards, so the mistake surfaces far from where it was made.

Check it: Look at the flags at the open call rather than at the failing call. If the read-write flag is absent, that is the whole answer.

An object was created as a token object without needing to be

An object marked as a token object is written to persistent storage, and that is a modification. The same object without that attribute lives in the session, needs no writable session, and disappears when the session closes, which for a working key is usually what you wanted.

Check it: Check the token attribute in the template you passed. If the key does not need to outlive the session, clear it and the error goes away without any change to how the session is opened.

A public read-only session, where the specification allows less than people expect

Before login, a session is limited in what it may touch, and some libraries report that limitation through this code rather than through the login-related one. The result is an error that says read-only when the real problem is that nobody has logged in.

Check it: Log in and retry the identical call. If it succeeds, the session was never the problem.

Which calls return it

C_CreateObject, C_DestroyObject, C_SetAttributeValue, C_GenerateKeyPair

What it is not

It is not about file permissions or the account the process runs as. The read-only property belongs to the session, and it was set by your own code at open time.

Often confused with

  • CKR_TOKEN_WRITE_PROTECTED: The token itself refuses writes, so no session on it can be writable. Opening the session differently will not help.
  • CKR_USER_NOT_LOGGED_IN: The other reason a write is refused. Worth ruling out before changing how sessions are opened.

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.