QMail Object Capabilities — Group 6, Code 83
Returns the live server's current limits and storage-class offerings. This is the authoritative source when it differs from cached discovery data, and requires no existing transfer or coin authentication.
Quick reference
| Command Group | 6 |
| Command Code | 83 |
| Server function | cmd_qmail_object_capabilities in qmail_object_transfer.c |
| Wire structures | qmail_object_capabilities_resp_t, qmail_object_storage_class_t |
| Body layout | Preamble (48) + Common prefix (16) = 64 bytes request header, no command-specific fields |
| Transport | TCP only |
| Encryption | Required — AES-128 |
| Authentication | No coin/AN lookup required — a valid encrypted request is sufficient |
Purpose
A client uses object_capabilities to learn a QMail storage server's current limits before, or independent of, any transfer: maximum object size, preferred and maximum chunk sizes, maximum download range, active-transfer quotas, storage classes and their capacity, and the server's payment mode. This live response overrides any cached discovery/DRD data — the server may lower limits at any time, and a client must not continue allocating or retrying blindly when a live limit differs from what it previously cached.
Calling this command requires no prior object_begin and no active transfer; it is a pure read of server policy, wrapped only in the standard QMail preamble and common prefix — there is no command-specific request payload at all.
Request body
Preamble (48 bytes, offsets 0–47)
Standard QMail preamble. See QMail Overview — Universal preamble.
Common prefix (16 bytes, offsets 48–63) — the entire request body
See object_begin for the shared common-prefix field table. command_header_length must equal 0 for this command — there is nothing after the common prefix.
Total request body length: 16 (challenge) + 32 (identity preamble) + 16 (common prefix) + 2 (terminator) = 66 bytes.
Response body
Successful response fixed header length: 80 bytes (16-byte common prefix + 64-byte capabilities response), followed by class_count 64-byte storage-class entries.
| Field | Size | Description |
|---|---|---|
| common_prefix | 16 | Echoes request_id. |
| capability_schema | 2 | Currently 1. |
| protocol_min | 2 | Lowest Object Transfer protocol version this server accepts. Currently 1. |
| protocol_max | 2 | Highest Object Transfer protocol version this server accepts. Currently 1. |
| transport_flags | 2 | Bit 0 = TCP supported. |
| server_flags | 4 | Bit 0 = object transfer enabled, bit 1 = replacement supported, bit 2 = deletion supported, bit 3 = legacy locker-marker payment, bit 4 = Phase I allow-all reads. |
| preferred_chunk | 4 | The server's preferred upload chunk size, offered when a client's object_begin requests preferred_chunk=0. |
| max_chunk | 4 | The largest upload chunk this server will accept. |
| max_download_range | 4 | The largest range object_get_range will return in one call. |
| max_active_transfers | 4 | Server-wide concurrent-transfer limit. |
| max_parallel_transfer | 2 | Maximum concurrent put_range calls the server will accept per transfer. |
| class_count | 2 | Number of 64-byte storage-class entries that follow (0..64). |
| max_object_global | 8 | Server-wide maximum object size. Each class's own max_object may be lower; the lower applicable value wins. |
| generated_at | 8 | Unix seconds when this response was generated. |
| expires_at | 8 | Unix seconds. 0 means this live response has no advertised cache lifetime; otherwise clients must refresh after this time. |
| payment_mode | 2 | 1 = legacy_locker_marker (the only Phase I mode). |
| reserved | 6 | Zero. |
| class entries | class_count × 64 | One entry per storage class; see the table below. |
Storage-class entry (64 bytes each)
| Field | Size | Description |
|---|---|---|
| class_id | 2 | Matches the storage_class value clients pass at object_begin. |
| media_type | 1 | 1 RAM, 2 NVMe, 3 SSD, 4 HDD, 255 other. |
| class_flags | 1 | Bit 0 = volatile (may not survive process/host failure). |
| max_object | 8 | This class's own maximum object size. At least 1. |
| capacity_bytes | 8 | Total class capacity. 0 means not disclosed, not zero capacity. |
| available_bytes | 8 | Advisory remaining capacity; may change immediately. Successful reservation by object_begin is authoritative, not this field. |
| max_retention_seconds | 8 | 0 means server policy decides; otherwise the maximum retention this class will accept. |
| price_schedule_id | 4 | Opaque identifier for the fee schedule associated with this class. |
| reserved | 24 | Zero. |
Status codes
| Code | Symbol | Meaning |
|---|---|---|
| 250 | SUCCESS | Capabilities returned; see response body. |
| 218 | ERROR_TCP_REQUIRED | Retry using TCP. |
| 219 | ERROR_UNSUPPORTED_PROTOCOL | Unsupported protocol_version or framing version. |
Common mistakes
Trusting cached capabilities indefinitely
A future DRD-signed capability record is advisory discovery information and may be stale. This command's live response is authoritative whenever it disagrees with cached data, and a client should re-query it (or check expires_at) rather than continuing to plan uploads against out-of-date limits.
Treating available_bytes as a reservation guarantee
available_bytes is advisory and can change the instant after this response is generated. The only authoritative signal that capacity was actually reserved is a successful object_begin response, not a prior capabilities check.