ERROR response for negative expiration values in memcached's set command
0 reputation · 12 Jul 2025, 00:14 UTC
0 reputation · 12 Jul 2025, 00:14 UTC
Memcached's protocol parser rejects negative expiration integers with an ERROR response, but the server performs no time-zone conversion for absolute expiration timestamps. When an expiration value exceeds REALTIME_MAXDELTA (30 days), memcached interprets it as a Unix timestamp expressed in UTC seconds since the epoch.
A client that calculates this timestamp from a regional local time without converting to UTC may supply a value that is already in the past relative to the server's UTC clock, causing the item to be treated as expired immediately. This creates a gap between explicit validation and silent failure: negative values produce a clear protocol error, while time-zone miscalculations produce no error at all.
The server stores expiration as a 32-bit unsigned integer, and behavior for oversized values can differ between 32-bit and 64-bit builds, adding further uncertainty for clients that derive timestamps dynamically. Given that memcached delegates all time-zone responsibility to the client, what is the correct boundary between client-side UTC normalization and server-side validation? Should clients treat past absolute timestamps as a configuration error to detect before issuing the command, or is there a server-side mechanism to surface this condition? How do 32-bit versus 64-bit builds affect the safe upper bound for client-generated expiration timestamps?
33275 reputation · 12 Jul 2025, 05:41 UTC
The correct boundary is that all UTC normalization and past-date validation must occur on the client side. Memcached is designed as a high-performance key-value store that delegates time-zone logic to the client to avoid the overhead of server-side clock synchronization or time-zone lookups per request.
Because the server only validates that the expiration integer is non-negative, it cannot distinguish between a legitimate absolute timestamp and a miscalculated one that happens to be in the past. Consequently, there is no server-side mechanism to surface a "past timestamp" as an error; the server simply treats the item as already expired.
To prevent silent failures caused by regional time-zone offsets, clients should implement the following logic before issuing a set command:
REALTIME_MAXDELTA (2,592,000 seconds) to avoid epoch-based calculations entirely.The safe upper bound for expiration timestamps is primarily governed by the 32-bit unsigned integer limit (0xFFFFFFFF), which corresponds to the "Year 2038" problem. The architectural difference affects how values exceeding this limit are handled:
| Build Architecture | Behavior for Oversized Values (> 32-bit) | Safe Upper Bound |
|---|---|---|
| 32-bit | Values are typically truncated to 32 bits, potentially resulting in a timestamp in the past. | 2^32 - 1 |
| 64-bit | Internal comparisons may handle 64-bit integers, but storage typically remains 32-bit unsigned. | 2^32 - 1 |
To ensure cross-platform consistency, clients should cap absolute timestamps at 4,294,967,295. Any value exceeding this should be treated as an invalid input to avoid unpredictable truncation behavior across different server builds.
You can verify this behavior using telnet or nc:
set key 0 10 -1 5 $\rightarrow$ Expect ERROR.current_utc - 86400). set key 0 [past_timestamp] 5 $\rightarrow$ Expect STORED, but get key will return NOT_FOUND.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.