{"record":{"id":"2be58b8ee837b7f1","repo":"apache/hadoop","slug":"policy-newpolicy-cannot-be-set-after-file","errorCode":null,"errorMessage":"\"Policy \" + newPolicy + \" cannot be set after file creation.\"","messagePattern":"\"Policy \" \\+ newPolicy \\+ \" cannot be set after file creation\\.\"","errorType":"exception","errorClass":"HadoopIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java","lineNumber":449,"sourceCode":"  }\n\n  static void unprotectedSetStoragePolicy(FSDirectory fsd, BlockManager bm,\n      INodesInPath iip, final byte policyId)\n      throws IOException {\n    assert fsd.hasWriteLock();\n    final INode inode = iip.getLastINode();\n    if (inode == null) {\n      throw new FileNotFoundException(\"File/Directory does not exist: \"\n          + iip.getPath());\n    }\n    final int snapshotId = iip.getLatestSnapshotId();\n    if (inode.isFile()) {\n      FSDirectory.LOG.debug(\"DIR* FSDirAAr.unprotectedSetStoragePolicy for \" +\n              \"File.\");\n      if (policyId != HdfsConstants.BLOCK_STORAGE_POLICY_ID_UNSPECIFIED) {\n        BlockStoragePolicy newPolicy = bm.getStoragePolicy(policyId);\n        if (newPolicy.isCopyOnCreateFile()) {\n          throw new HadoopIllegalArgumentException(\"Policy \" + newPolicy\n              + \" cannot be set after file creation.\");\n        }\n      }\n\n      BlockStoragePolicy currentPolicy =\n          bm.getStoragePolicy(inode.getLocalStoragePolicyID());\n\n      if (currentPolicy != null && currentPolicy.isCopyOnCreateFile()) {\n        throw new HadoopIllegalArgumentException(\n            \"Existing policy \" + currentPolicy.getName() +\n                \" cannot be changed after file creation.\");\n      }\n      inode.asFile().setStoragePolicyID(policyId, snapshotId);\n    } else if (inode.isDirectory()) {\n      FSDirectory.LOG.debug(\"DIR* FSDirAAr.unprotectedSetStoragePolicy for \" +\n              \"Directory.\");\n      setDirStoragePolicy(fsd, iip, policyId);\n    } else {","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java#L431-L467","documentation":"Policies flagged copyOnCreateFile can only be assigned at file creation because they change where new blocks are placed as the file is written. In the default suite LAZY_PERSIST is the only such policy (BlockStoragePolicySuite marks it 'Cannot be changed on regular files, but inherited'), and applying it to an already-created file throws HadoopIllegalArgumentException.","triggerScenarios":"setStoragePolicy(file, 'LAZY_PERSIST') on an existing file, or 'hdfs storagepolicies -setStoragePolicy -policy LAZY_PERSIST <existing-file>': the target policy isCopyOnCreateFile() and the inode is a regular file (not a directory).","commonSituations":"Trying to move existing hot data into RAM_DISK to speed up reads; blanket policy rollout scripts applying LAZY_PERSIST across existing trees instead of directories.","solutions":["Apply LAZY_PERSIST to the parent directory instead - new children inherit it at creation time (directory policy setting is allowed).","For existing data, rewrite: put the directory under the lazy-persist policy (or create with CreateFlag.LAZY_PERSIST), create the new file, copy the bytes.","For data that must stay appendable, avoid LAZY_PERSIST entirely - append on lazy-persist files is separately unsupported."],"exampleFix":"# before: rejected, cannot set after creation\nhdfs storagepolicies -setStoragePolicy -policy LAZY_PERSIST /data/exists.txt\n\n# after: set on the directory; new files inherit at creation\nhdfs storagepolicies -setStoragePolicy -policy LAZY_PERSIST /data","handlingStrategy":"validation","validationCode":"BlockStoragePolicy[] policies = ((DistributedFileSystem) fs).getStoragePolicies();\nBlockStoragePolicy target = Arrays.stream(policies)\n    .filter(p -> p.getName().equals(policyName)).findFirst().orElse(null);\nboolean isExistingFile = fs.exists(path) && fs.getFileStatus(path).isFile();\nif (target != null && target.isCopyOnCreateFile() && isExistingFile) {\n  // apply to the parent directory instead so children inherit at creation\n  fs.setStoragePolicy(path.getParent(), policyName);\n} else {\n  fs.setStoragePolicy(path, policyName);\n}","typeGuard":null,"tryCatchPattern":"try {\n  fs.setStoragePolicy(path, policyName);\n} catch (HadoopIllegalArgumentException e) {\n  if (e.getMessage().contains(\"cannot be set after file creation\")) {\n    // copy-on-create policy (LAZY_PERSIST): set on the directory or rewrite the file\n  }\n}","preventionTips":["Apply copy-on-create policies to directories, never to existing files.","Flag isCopyOnCreateFile() policies in rollout configs so scripts can special-case them."],"tags":["hdfs","storage-policy","lazy-persist","copy-on-create"],"backgroundTag":"copy-on-create-policy","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}