{"record":{"id":"de369583f580673d","repo":"apache/hadoop","slug":"unlinktmpfile-unlinktmpfile-does-not-end-with-u","errorCode":null,"errorMessage":"unlinkTmpFile={unlinkTmpFile} does not end with .unlinked","messagePattern":"unlinkTmpFile=(.+?) does not end with \\.unlinked","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetUtil.java","lineNumber":77,"sourceCode":"    DataChecksum csum =\n        DataChecksum.newDataChecksum(DataChecksum.Type.NULL, 512);\n    ByteArrayOutputStream out = new ByteArrayOutputStream();\n    DataOutputStream dataOut = new DataOutputStream(out);\n    try {\n      BlockMetadataHeader.writeHeader(dataOut, csum);\n      dataOut.close();\n    } catch (IOException e) {\n      FsVolumeImpl.LOG.error(\n          \"Exception in creating null checksum stream: \" + e);\n      return null;\n    }\n    return out.toByteArray();\n  }\n\n  static File getOrigFile(File unlinkTmpFile) {\n    final String name = unlinkTmpFile.getName();\n    if (!name.endsWith(DatanodeUtil.UNLINK_BLOCK_SUFFIX)) {\n      throw new IllegalArgumentException(\"unlinkTmpFile=\" + unlinkTmpFile\n          + \" does not end with \" + DatanodeUtil.UNLINK_BLOCK_SUFFIX);\n    }\n    final int n = name.length() - DatanodeUtil.UNLINK_BLOCK_SUFFIX.length(); \n    return new File(unlinkTmpFile.getParentFile(), name.substring(0, n));\n  }\n  \n  static File getMetaFile(File f, long gs) {\n    return new File(f.getParent(),\n        DatanodeUtil.getMetaName(f.getName(), gs));\n  }\n\n  /** Find the corresponding meta data file from a given block file */\n  public static File findMetaFile(final File blockFile) throws IOException {\n    final String prefix = blockFile.getName() + \"_\";\n    final File parent = blockFile.getParentFile();\n    final File[] matches = parent.listFiles(new FilenameFilter() {\n      @Override\n      public boolean accept(File dir, String name) {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetUtil.java#L59-L95","documentation":"FsDatasetUtil.getOrigFile maps a hard-link-breaking temp file named '<original>.unlinked' back to its original path. The IllegalArgumentException fires when the supplied File's name lacks DatanodeUtil.UNLINK_BLOCK_SUFFIX ('.unlinked') - internal code passed a regular block or meta file where an unlinked temp was required.","triggerScenarios":"Dataset code breaking hard links for append/truncate passing the wrong File; directory scans encountering foreign files with similar names; test helpers constructing file names by hand.","commonSituations":"Custom FsDatasetSpi extensions or unit tests; stray manually created files in rbw/tmp directories; extremely rare in stock deployments.","solutions":["Inspect the exact path in the message - if it is not a DN-created '.unlinked' temp, move the file out of the replica directories.","If it recurs during recovery, capture the preceding replica operation and check your release for patched bugs; upgrade.","Keep replica directories free of foreign files; DN scans expect only HDFS-managed names."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!tmpFile.getName().endsWith(DatanodeUtil.UNLINK_BLOCK_SUFFIX)) {\n  // not an unlinked temp file; do not call getOrigFile\n  return null;\n}\nFile orig = FsDatasetUtil.getOrigFile(tmpFile);","typeGuard":"static boolean isUnlinkedTemp(File f) {\n  return f != null && f.getName().endsWith(DatanodeUtil.UNLINK_BLOCK_SUFFIX);\n}","tryCatchPattern":"try {\n  orig = FsDatasetUtil.getOrigFile(f);\n} catch (IllegalArgumentException e) {\n  // wrong file type passed: skip and log the path\n}","preventionTips":["Validate the '.unlinked' suffix before calling getOrigFile.","Never place foreign files in rbw/tmp/finalized replica directories.","In tests, build file names via DatanodeUtil.getMetaName instead of string concatenation."],"tags":["hdfs","datanode","file-naming","unlink","argument-validation"],"backgroundTag":"hdfs-invalid-block-file-name","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}