apache/hadoop · error · InvalidRequestException
Max relative expiry is too big.
Error message
Max relative expiry is too big.
What it means
CachePoolInfo.validate() rejects maxRelativeExpiryMs greater than Expiration.MAX_RELATIVE_EXPIRY_MS. That constant (about 2.5 years in ms) is the largest relative expiry the system can represent internally; larger values would overflow absolute-expiry computations.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/CachePoolInfo.java:235
public static void validate(CachePoolInfo info) throws IOException {
if (info == null) {
throw new InvalidRequestException("CachePoolInfo is null");
}
if ((info.getLimit() != null) && (info.getLimit() < 0)) {
throw new InvalidRequestException("Limit is negative.");
}
if ((info.getDefaultReplication() != null)
&& (info.getDefaultReplication() < 0)) {
throw new InvalidRequestException("Default Replication is negative");
}
if (info.getMaxRelativeExpiryMs() != null) {
long maxRelativeExpiryMs = info.getMaxRelativeExpiryMs();
if (maxRelativeExpiryMs < 0l) {
throw new InvalidRequestException("Max relative expiry is negative.");
}
if (maxRelativeExpiryMs > Expiration.MAX_RELATIVE_EXPIRY_MS) {
throw new InvalidRequestException("Max relative expiry is too big.");
}
}
validateName(info.poolName);
}
public static void validateName(String poolName) throws IOException {
if (poolName == null || poolName.isEmpty()) {
// Empty pool names are not allowed because they would be highly
// confusing. They would also break the ability to list all pools
// by starting with prevKey = ""
throw new IOException("invalid empty cache pool name");
}
}
}
View on GitHub (pinned to 2add963021)
Solutions
- For 'never expire' semantics use Expiration.MAX_RELATIVE_EXPIRY_MS exactly, not Long.MAX_VALUE.
- Clamp: long expiry = Math.min(Expiration.MAX_RELATIVE_EXPIRY_MS, requestedMs);
- Double-check unit conversions to milliseconds.
Example fix
// before info.setMaxRelativeExpiryMs(Long.MAX_VALUE); // 'forever' // after info.setMaxRelativeExpiryMs(Expiration.MAX_RELATIVE_EXPIRY_MS);
Defensive patterns
Strategy: validation
Validate before calling
long clamped = Math.min(Expiration.MAX_RELATIVE_EXPIRY_MS, Math.max(0L, requestedExpiryMs)); info.setMaxRelativeExpiryMs(clamped);
Try / catch
try { dfs.addCachePool(info); }
catch (InvalidRequestException e) { /* requested expiry exceeds representable max — clamp upstream */ } Prevention
- Never use Long.MAX_VALUE for 'forever'; use Expiration.MAX_RELATIVE_EXPIRY_MS.
- Add a unit-test asserting generated expiries stay within [0, MAX_RELATIVE_EXPIRY_MS].
- Review day/ms conversions once in a shared utility instead of at each call site.
When it happens
Trigger: setMaxRelativeExpiryMs with a value above Expiration.MAX_RELATIVE_EXPIRY_MS, commonly from passing Long.MAX_VALUE intending 'forever', or from a milliseconds-vs-days unit error.
Common situations: Copy-paste of Long.MAX_VALUE as 'unlimited'; unit confusion multiplying days*24*60*60 but forgetting 1000 (or doubling it).
Related errors
- Max relative expiry is negative.
- Limit is negative.
- Default Replication is negative
- invalid empty cache pool name
- Path part {s} from URI {p} is not a valid filename.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f9993f3d5e8110e1.
Report an issue: GitHub.