This error occurs when you try to set a Redis key with an invalid expiration time, typically because the expire duration is negative, zero, or overflowed. Learn how to fix this common SET command issue.
Redis requires expiration times (TTL) to be positive integers when using the SET command with EX (seconds) or PX (milliseconds) options. This error is returned by the Redis server when the provided expire time value is invalid - most commonly when it's zero, negative, or has overflowed the integer bounds. The error can occur with any of these SET command variants: SET key value EX seconds, SET key value PX milliseconds, SET key value EXAT timestamp, or SET key value PXAT timestamp. The underlying issue is that Redis validates the expire time before setting the key, and rejects any non-positive duration.
Check that any expiration time you're passing to SET is greater than zero. This is the most common cause.
# WRONG - will fail with invalid expire time
SET mykey "value" EX 0
SET mykey "value" EX -10
# CORRECT - use positive integers
SET mykey "value" EX 60
SET mykey "value" EX 3600If using a client library in your code, verify the TTL value before passing it to Redis:
// JavaScript example
const ttl = calculateTTL(); // Make sure this returns > 0
if (ttl <= 0) {
console.error("Invalid TTL:", ttl);
return; // Or use TTL of 1 as minimum
}
await redis.set(key, value, "EX", ttl);If you're calculating TTL by subtracting timestamps, ensure the result is always positive. This is common with session handling.
// WRONG - if expiryTime is in the past, ttl becomes negative
const ttl = Math.floor((expiryTime - Date.now()) / 1000);
await redis.set(sessionKey, data, "EX", ttl); // Fails if ttl < 0
// CORRECT - validate the result
const ttl = Math.floor((expiryTime - Date.now()) / 1000);
if (ttl <= 0) {
// Key is already expired, skip setting or use minimum TTL
console.warn("Session already expired");
return;
}
await redis.set(sessionKey, data, "EX", ttl);Or use the max() function to ensure a minimum value:
const ttl = Math.max(1, Math.floor((expiryTime - Date.now()) / 1000));
await redis.set(sessionKey, data, "EX", ttl);If using connect-redis or express-session, ensure session cookies don't expire in the past. Enable rolling sessions to refresh TTL on each request.
// express-session configuration
const sessionConfig = {
store: new RedisStore({ client: redisClient }),
secret: "your-secret-key",
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
maxAge: 14 * 24 * 60 * 60 * 1000, // 14 days
},
rolling: true, // Refresh session TTL on each request
};The key is setting rolling: true, which refreshes the session expiration on every request, preventing the edge case where a session hits exactly maxAge since creation.
If you're updating a key and want to preserve its current TTL, use the KEEPTTL option (Redis 6.0+) instead of recalculating the expiration time.
# Preserves the existing TTL while updating the value
SET mykey "new_value" KEEPTTLThis eliminates the need to calculate or pass an expire time, avoiding calculation errors:
// No need to manage TTL for updates
await redis.set(key, newValue, "KEEPTTL");When using EXPIREAT or PXAT with Unix timestamps, ensure the timestamp is in the future. Redis will immediately delete keys if you set an expiration time in the past.
Integer overflow can occur in some client libraries or language bindings. If calculations involve large numbers or time conversions, ensure your language's integer type can safely hold the values (typically int64 for seconds, int64 for milliseconds). Values like -2147483648 (32-bit integer minimum) may cause unexpected behavior.
For high-throughput applications, consider using pipelining to batch SET commands and reduce round-trips to Redis, but always ensure TTL values are pre-validated before entering the pipeline.
ERR Unbalanced XREAD list of streams
How to fix "ERR Unbalanced XREAD list" in Redis
ERR syntax error
How to fix "ERR syntax error" in Redis
ConnectionError: Error while reading from socket
ConnectionError: Error while reading from socket in redis-py
ERR unknown command
How to fix ERR unknown command in Redis
Command timed out
How to fix 'Command timed out' in ioredis