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

  1. For 'never expire' semantics use Expiration.MAX_RELATIVE_EXPIRY_MS exactly, not Long.MAX_VALUE.
  2. Clamp: long expiry = Math.min(Expiration.MAX_RELATIVE_EXPIRY_MS, requestedMs);
  3. 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

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


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/f9993f3d5e8110e1. Report an issue: GitHub.