Error codes
An ERROR frame contains a one-byte code and a human-readable reason (see
the frame layout). Clients branch
on the code only, never on the text.
| Code | Meaning | Class |
|---|---|---|
0x01 |
server shutting down | server condition |
0x02 |
closed by administrator (force-release / kick) | server condition |
0x10 |
unsupported protocol version | client error |
0x11 |
first message must be ACQUIRE | client error |
0x12 |
duplicate ACQUIRE | client error |
0x13 |
unknown message type | client error |
0x14 |
empty lock name | client error |
0x15 |
lock name too long (> 255 bytes) | client error |
0x16 |
lock name is not valid UTF-8 | client error |
0x17 |
lease must be positive | client error |
0x18 |
not authorized for lock (access-control list (ACL)) | client error |
The retry contract
Section titled “The retry contract”The division is a range, not a list:
- Codes below
0x10are server conditions. There is no problem in the client. The correct reaction is to connect again: immediately after a shutdown handover (0x01), and with backoff for the other codes. - Codes at
0x10and above are client errors. The same bytes will fail in the same way. The correct reaction is to report the error and stop, not to retry.
The division is a range. Thus a client classifies unknown codes in the same
way. A future server condition below 0x10 gets a retry. A future client
error at 0x10 or above gets a report. This rule keeps old clients correct
against newer servers.
The reason string
Section titled “The reason string”The reason is a UTF-8 string for error messages and debugging. It contains
the canonical text of the code, sometimes with more detail — unknown message type: 0x7f — and it can be empty. It is not a part of the contract,
and it can change between server versions. Do not parse it.
Observability
Section titled “Observability”The server counts each sent ERROR in monolock_protocol_errors_total{code}
(metrics). Thus a class of incorrect
clients is visible as a counter that increases, with the wire code as a
label. ACL denials (0x18) also count in monolock_acl_denials_total, and
they appear in the audit log as denied events.

