{"record":{"id":"f9993f3d5e8110e1","repo":"apache/hadoop","slug":"max-relative-expiry-is-too-big","errorCode":null,"errorMessage":"Max relative expiry is too big.","messagePattern":"Max relative expiry is too big\\.","errorType":"exception","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/CachePoolInfo.java","lineNumber":235,"sourceCode":"  public static void validate(CachePoolInfo info) throws IOException {\n    if (info == null) {\n      throw new InvalidRequestException(\"CachePoolInfo is null\");\n    }\n    if ((info.getLimit() != null) && (info.getLimit() < 0)) {\n      throw new InvalidRequestException(\"Limit is negative.\");\n    }\n    if ((info.getDefaultReplication() != null)\n            && (info.getDefaultReplication() < 0)) {\n      throw new InvalidRequestException(\"Default Replication is negative\");\n    }\n\n    if (info.getMaxRelativeExpiryMs() != null) {\n      long maxRelativeExpiryMs = info.getMaxRelativeExpiryMs();\n      if (maxRelativeExpiryMs < 0l) {\n        throw new InvalidRequestException(\"Max relative expiry is negative.\");\n      }\n      if (maxRelativeExpiryMs > Expiration.MAX_RELATIVE_EXPIRY_MS) {\n        throw new InvalidRequestException(\"Max relative expiry is too big.\");\n      }\n    }\n    validateName(info.poolName);\n  }\n\n  public static void validateName(String poolName) throws IOException {\n    if (poolName == null || poolName.isEmpty()) {\n      // Empty pool names are not allowed because they would be highly\n      // confusing.  They would also break the ability to list all pools\n      // by starting with prevKey = \"\"\n      throw new IOException(\"invalid empty cache pool name\");\n    }\n  }\n}\n","sourceCodeStart":217,"sourceCodeEnd":250,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/protocol/CachePoolInfo.java#L217-L250","documentation":"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.","triggerScenarios":"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.","commonSituations":"Copy-paste of Long.MAX_VALUE as 'unlimited'; unit confusion multiplying days*24*60*60 but forgetting 1000 (or doubling it).","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."],"exampleFix":"// before\ninfo.setMaxRelativeExpiryMs(Long.MAX_VALUE); // 'forever'\n\n// after\ninfo.setMaxRelativeExpiryMs(Expiration.MAX_RELATIVE_EXPIRY_MS);","handlingStrategy":"validation","validationCode":"long clamped = Math.min(Expiration.MAX_RELATIVE_EXPIRY_MS, Math.max(0L, requestedExpiryMs));\ninfo.setMaxRelativeExpiryMs(clamped);","typeGuard":null,"tryCatchPattern":"try { dfs.addCachePool(info); }\ncatch (InvalidRequestException e) { /* requested expiry exceeds representable max — clamp upstream */ }","preventionTips":["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."],"tags":["hdfs","caching","validation","expiration","overflow"],"backgroundTag":"input-validation-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}