apache/cassandra · error · InvalidRequestException
Request on table . with %sttl of seconds exceeds maximum…
Error message
Request on table %s.%s with %sttl of %d seconds exceeds maximum supported expiration date of %s. In order to avoid this use a lower TTL, change the expiration date overflow policy or upgrade to a version where this limitation is fixed. See CASSANDRA-14092 and CASSANDRA-14227 for more details.
What it means
When a write's TTL (with its local expiration timestamp) would produce an expiration date beyond the maximum representable value, and the configured policy is EXPIRATION_DATE_OVERFLOW_POLICY = REJECT, ExpirationDateOverflowHandling.maybeApplyExpirationDateOverflowPolicy throws InvalidRequestException, rejecting the write (INSERT/UPDATE with TTL).
Solutions
- Lower the TTL in the write (or in ttl_in_seconds default) so the expiration date stays within the maximum (e.g. use seconds not decades).
- Change expiration_date_overflow_policy in cassandra.yaml from REJECT to CAP (or WARN) if clamping the expiration is acceptable.
- Upgrade to a fixed version where the maximum supported expiration date is extended (CASSANDRA-14092/CASSANDRA-14227).
- Fix application code that computes TTL (e.g. passing epoch-based seconds instead of a relative TTL).
Example fix
// before: rejected write INSERT INTO sensors (id, temp) VALUES (1, 20.5) USING TTL 630720000; // after: smaller TTL within supported range INSERT INTO sensors (id, temp) VALUES (1, 20.5) USING TTL 31536000;
Defensive patterns
Strategy: validation
Validate before calling
int maxTtl = (int) ((ExpirationDateOverflowHandling.getMaxExpirationDateTS() - System.currentTimeMillis()) / 1000); if (ttl > maxTtl) ttl = maxTtl; // or reject client-side
Try / catch
try {
session.execute(insertWithTtl(ttl));
} catch (InvalidRequestException e) {
if (e.getMessage().contains("exceeds maximum supported expiration date"))
retryWithClampedTtl(ttl); // lower TTL or use CAP policy server-side
else throw e;
}
Prevention
- Compute TTLs as relative seconds, never epoch-like absolute values.
- Set expiration_date_overflow_policy=CAP if clamping is acceptable for your workload.
- Cap TTL at the application layer (e.g. max 20 years minus clock skew).
- Upgrade past CASSANDRA-14092/14227 fixes for extended max expiration dates.
When it happens
Trigger: An INSERT/UPDATE (or batch) sets a very large TTL (default TTL exceeding max_expiration_date_overflow_policy limits, or explicit USING TTL <n>) such that localExpirationTime + ttl exceeds MAXIMUM_EXPIRATION_DATE (~2038/2106 boundary depending on build).
Common situations: Misconfigured default TTL of huge values (e.g. ttl_in_seconds = 630720000 with REJECT policy and an older build); application code passing seconds-in-decades as TTL; clusters that predate the CASSANDRA-14092/14227 fixes where the maximum expiration is capped at 2038 (int seconds).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- A TTL must be greater or equal to 0, but was
- property was set to seconds which is not in allowed range…
- Request on table . with ttl of seconds exceeds maximum…
- Triggers are present but TriggersPolicy.forbidden is…
- ttl is too large. requested
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8b2125994dfbbf68.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/ExpirationDateOverflowHandling.java:105
case CAP:
ClientWarn.instance.warn(MessageFormatter.arrayFormat(MAXIMUM_EXPIRATION_DATE_EXCEEDED_WARNING, new Object[] { metadata.keyspace,
metadata.name,
isDefaultTTL? "default " : "",
ttl,
getMaxExpirationDateTS()})
.getMessage());
case CAP_NOWARN:
/**
* Capping at this stage is basically not rejecting the request. The actual capping is done
* by {@link #computeLocalExpirationTime(long, int)}, which converts the negative TTL
* to {@link org.apache.cassandra.db.BufferExpiringCell#MAX_DELETION_TIME}
*/
NoSpamLogger.log(logger, NoSpamLogger.Level.WARN, EXPIRATION_OVERFLOW_WARNING_INTERVAL_MINUTES, TimeUnit.MINUTES, MAXIMUM_EXPIRATION_DATE_EXCEEDED_WARNING,
metadata.keyspace, metadata.name, isDefaultTTL? "default " : "", ttl, getMaxExpirationDateTS());
return;
default:
throw new InvalidRequestException(String.format(MAXIMUM_EXPIRATION_DATE_EXCEEDED_REJECT_MESSAGE, metadata.keyspace, metadata.name,
isDefaultTTL? "default " : "", ttl, getMaxExpirationDateTS()));
}
}
}
/**
* This method computes the {@link Cell#localDeletionTime()}, maybe capping to the maximum representable value
* which is {@link Cell#MAX_DELETION_TIME}.
*
* Please note that the {@link ExpirationDateOverflowHandling.ExpirationDateOverflowPolicy} is applied
* during {@link ExpirationDateOverflowHandling#maybeApplyExpirationDateOverflowPolicy(org.apache.cassandra.schema.TableMetadata, int, boolean)},
* so if the request was not denied it means its expiration date should be capped.
*
* See CASSANDRA-14092
*/
public static long computeLocalExpirationTime(long nowInSec, int timeToLive)
{
View on GitHub (pinned to 88fd0f6a0e)