apache/cassandra · error · InvalidRequestException
ttl is too large. requested (%d) maximum (%d)
Error message
ttl is too large. requested (%d) maximum (%d)
What it means
Cassandra caps USING TTL at MAX_TTL (20 years, 630720000 seconds) because stored expiration timestamps are 32-bit; larger TTLs would overflow. getTimeToLive throws InvalidRequestException 'ttl is too large. requested (%d) maximum (%d)'. (Expiration-date overflow beyond 2038 is further handled by ExpirationDateOverflowHandling.)
Source
Thrown at src/java/org/apache/cassandra/cql3/Attributes.java:143
// identity, so need to check this after checking that
if (ByteBufferUtil.EMPTY_BYTE_BUFFER.equals(tval))
return 0;
try
{
Int32Type.instance.validate(tval);
}
catch (MarshalException e)
{
throw new InvalidRequestException("Invalid TTL value: " + tval);
}
int ttl = Int32Type.instance.compose(tval);
if (ttl < 0)
throw new InvalidRequestException("A TTL must be greater or equal to 0, but was " + ttl);
if (ttl > MAX_TTL)
throw new InvalidRequestException(String.format("ttl is too large. requested (%d) maximum (%d)", ttl, MAX_TTL));
if (metadata.params.defaultTimeToLive != LivenessInfo.NO_TTL && ttl == LivenessInfo.NO_TTL)
return LivenessInfo.NO_TTL;
ExpirationDateOverflowHandling.maybeApplyExpirationDateOverflowPolicy(metadata, ttl, false);
return ttl;
}
public void collectMarkerSpecification(VariableSpecifications boundNames)
{
if (timestamp != null)
timestamp.collectMarkerSpecification(boundNames, this);
if (timeToLive != null)
timeToLive.collectMarkerSpecification(boundNames, this);
}
public static class RawView on GitHub (pinned to 88fd0f6a0e)
Solutions
- Cap the TTL client-side to 630720000 (20 years) or use TTL 0 for no expiry
- Convert milliseconds to seconds before binding (ms / 1000)
- Express 'never expire' as TTL 0 rather than a very large number
- Review retention logic so computed TTLs stay within 32-bit-second limits
Example fix
// before int ttl = (int) (retentionMs / 1); // wrong unit, huge value // after int ttl = (int) Math.min(retentionMs / 1000, 630720000L); // seconds, <= MAX_TTL
Defensive patterns
Strategy: validation
Validate before calling
static final int MAX_TTL = 630720000; // 20 years
int clampTtl(long ttlSeconds) {
return (int) Math.min(Math.max(ttlSeconds, 0), MAX_TTL);
} Type guard
boolean isTtlWithinLimit(long ttl) { return ttl >= 0 && ttl <= 630720000L; } Try / catch
try {
session.execute(bs);
} catch (InvalidQueryException e) {
if (e.getMessage().startsWith("ttl is too large"))
log.error("TTL exceeds 20 years; convert ms->s or use TTL 0 for no expiry");
throw e;
} Prevention
- Convert milliseconds to seconds before binding TTL
- Cap retention TTLs at 630720000 seconds or use 0 for never-expire
- Never map Integer.MAX_VALUE or Long values into USING TTL
- Document the 20-year TTL limit in client SDKs
When it happens
Trigger: 'USING TTL ?' bound with an int > 630720000 (20 years); e.g. computing a TTL in seconds from a multi-decade retention period or accidentally using milliseconds (e.g. 31536000000 = 1000 years in ms).
Common situations: Retention policies expressed in ms bound directly as TTL seconds; 'infinite' retention encoded as Integer.MAX_VALUE; business rules like 'never expire' mapped to huge numbers.
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 <ttl>
- Invalid null value of timestamp
- Invalid TTL value: <tval>
- Global TTL on the BATCH statement is not supported.
- Counter and non-counter mutations cannot exist in the same b
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/3d7205c142d5accf.
Report an issue: GitHub.