apache/hadoop · error · IllegalArgumentException

unlinkTmpFile={unlinkTmpFile} does not end with .unlinked

Error message

unlinkTmpFile={unlinkTmpFile} does not end with .unlinked

What it means

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.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetUtil.java:77

    DataChecksum csum =
        DataChecksum.newDataChecksum(DataChecksum.Type.NULL, 512);
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    DataOutputStream dataOut = new DataOutputStream(out);
    try {
      BlockMetadataHeader.writeHeader(dataOut, csum);
      dataOut.close();
    } catch (IOException e) {
      FsVolumeImpl.LOG.error(
          "Exception in creating null checksum stream: " + e);
      return null;
    }
    return out.toByteArray();
  }

  static File getOrigFile(File unlinkTmpFile) {
    final String name = unlinkTmpFile.getName();
    if (!name.endsWith(DatanodeUtil.UNLINK_BLOCK_SUFFIX)) {
      throw new IllegalArgumentException("unlinkTmpFile=" + unlinkTmpFile
          + " does not end with " + DatanodeUtil.UNLINK_BLOCK_SUFFIX);
    }
    final int n = name.length() - DatanodeUtil.UNLINK_BLOCK_SUFFIX.length(); 
    return new File(unlinkTmpFile.getParentFile(), name.substring(0, n));
  }
  
  static File getMetaFile(File f, long gs) {
    return new File(f.getParent(),
        DatanodeUtil.getMetaName(f.getName(), gs));
  }

  /** Find the corresponding meta data file from a given block file */
  public static File findMetaFile(final File blockFile) throws IOException {
    final String prefix = blockFile.getName() + "_";
    final File parent = blockFile.getParentFile();
    final File[] matches = parent.listFiles(new FilenameFilter() {
      @Override
      public boolean accept(File dir, String name) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Inspect the exact path in the message - if it is not a DN-created '.unlinked' temp, move the file out of the replica directories.
  2. If it recurs during recovery, capture the preceding replica operation and check your release for patched bugs; upgrade.
  3. Keep replica directories free of foreign files; DN scans expect only HDFS-managed names.
Defensive patterns

Strategy: validation

Validate before calling

if (!tmpFile.getName().endsWith(DatanodeUtil.UNLINK_BLOCK_SUFFIX)) {
  // not an unlinked temp file; do not call getOrigFile
  return null;
}
File orig = FsDatasetUtil.getOrigFile(tmpFile);

Type guard

static boolean isUnlinkedTemp(File f) {
  return f != null && f.getName().endsWith(DatanodeUtil.UNLINK_BLOCK_SUFFIX);
}

Try / catch

try {
  orig = FsDatasetUtil.getOrigFile(f);
} catch (IllegalArgumentException e) {
  // wrong file type passed: skip and log the path
}

Prevention

When it happens

Trigger: 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.

Common situations: Custom FsDatasetSpi extensions or unit tests; stray manually created files in rbw/tmp directories; extremely rare in stock deployments.

Related errors


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