apache/hadoop · error · InvalidRequestException
Max relative expiry is negative.
Error message
Max relative expiry is negative.
What it means
CachePoolInfo.validate() throws when a pool's maxRelativeExpiryMs is set and negative. Max relative expiry bounds how far in the future directives in the pool may set their expiration; a negative duration is meaningless.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/CachePoolInfo.java:232
hashCode();
}
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
- Use a non-negative duration; use Expiration.MAX_RELATIVE_EXPIRY_MS for 'never expire'.
- Clamp computed expiries: long expiry = Math.max(0L, computedExpiryMs);
- Validate units (ms, not s) before calling setMaxRelativeExpiryMs.
Example fix
// before info.setMaxRelativeExpiryMs(endTimeMs - System.currentTimeMillis()); // can be negative // after long rel = Math.max(0L, endTimeMs - System.currentTimeMillis()); info.setMaxRelativeExpiryMs(rel);
Defensive patterns
Strategy: validation
Validate before calling
long maxExpiry = Math.max(0L, requestedExpiryMs); info.setMaxRelativeExpiryMs(maxExpiry);
Try / catch
try { dfs.addCachePool(info); }
catch (InvalidRequestException e) { /* reject the expiry input at the API boundary */ } Prevention
- Compute relative expiries as Math.max(0, end - now) — time deltas can go negative on clock skew.
- Keep all expiry math in milliseconds and name variables accordingly (…Ms).
- Validate external expiration input before it reaches CachePoolInfo.
When it happens
Trigger: addCachePool/modifyCachePool with setMaxRelativeExpiryMs(negative), e.g. computing 'now - lastExpiry' style values or unit conversion mistakes (passing a negative millisecond delta).
Common situations: Time arithmetic with System.currentTimeMillis() differences that can go negative, or passing seconds where milliseconds are expected via a negative sentinel.
Related errors
- Max relative expiry is too big.
- 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/8d7775cedb4f6d2e.
Report an issue: GitHub.