apache/hadoop · error · HadoopIllegalArgumentException

"concat: source file " + src + " is invalid or empty or unde

Error message

"concat: source file " + src + " is invalid or empty or underConstruction"

What it means

Each source must be a finalized, non-empty regular file: verifySrcFiles rejects srcs where isUnderConstruction() or numBlocks() == 0 with HadoopIllegalArgumentException. Concat splices existing block lists — an open file's block list is still mutating, and an empty file contributes nothing while still requiring inode deletion, so both are rejected up front.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirConcatOp.java:154

      // make sure all the source files are not in snapshot
      if (srcINode.isInLatestSnapshot(iip.getLatestSnapshotId())) {
        throw new SnapshotException("Concat: the source file " + src
            + " is in snapshot");
      }
      // check if the file has other references.
      if (srcINode.isReference() && ((INodeReference.WithCount)
          srcINode.asReference().getReferredINode()).getReferenceCount() > 1) {
        throw new SnapshotException("Concat: the source file " + src
            + " is referred by some other reference in some snapshot.");
      }
      // source file cannot be the same with the target file
      if (srcINode.equals(targetINode)) {
        throw new HadoopIllegalArgumentException("concat: the src file " + src
            + " is the same with the target file " + targetIIP.getPath());
      }
      // source file cannot be under construction or empty
      if(srcINodeFile.isUnderConstruction() || srcINodeFile.numBlocks() == 0) {
        throw new HadoopIllegalArgumentException("concat: source file " + src
            + " is invalid or empty or underConstruction");
      }

      // source file's preferred block size cannot be greater than the target
      // file
      if (srcINodeFile.getPreferredBlockSize() >
          targetINode.getPreferredBlockSize()) {
        throw new HadoopIllegalArgumentException("concat: source file " + src
            + " has preferred block size " + srcINodeFile.getPreferredBlockSize()
            + " which is greater than the target file's preferred block size "
            + targetINode.getPreferredBlockSize());
      }
      if(srcINodeFile.getErasureCodingPolicyID() !=
          targetINode.getErasureCodingPolicyID()) {
        throw new HadoopIllegalArgumentException("Source file " + src
            + " and target file " + targetIIP.getPath()
            + " have different erasure coding policy");
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Close (or recoverLease for crashed writers) every src before concat.
  2. Filter srcs by st.getLen() > 0 using getFileStatus — zero-length files have zero blocks.
  3. Filter out directories and anything that is not a regular file before building the src array.

Example fix

// before
fs.concat(target, dirListing(dir)); // may contain empty or open files

// after
List<Path> srcs = new ArrayList<>();
for (FileStatus st : fs.listStatus(dir)) {
  if (st.isFile() && st.getLen() > 0 && !st.getPath().equals(target)) {
    srcs.add(st.getPath());
  } // skip empty files and directories
}
if (!srcs.isEmpty()) fs.concat(target, srcs.toArray(new Path[0]));
Defensive patterns

Strategy: validation

Validate before calling

List<Path> ok = new ArrayList<>();
for (Path src : srcs) {
  FileStatus st = fs.getFileStatus(src);
  if (st.isFile() && st.getLen() > 0) ok.add(src); // 0 length => 0 blocks
}

Try / catch

catch (HadoopIllegalArgumentException e) {
  if (e.getMessage() != null && e.getMessage().contains("invalid or empty or underConstruction")) {
    recoverLeasesAndFilterEmpty(srcs); // close/recover open files, drop empties, retry concat
  } else { throw e; }
}

Prevention

When it happens

Trigger: Passing a still-open file (writer has not closed / lease not recovered) as a src; passing a zero-length file (created but never written, or truncated); passing a path that is a directory (INodeFile.valueOf would fail adjacent to this check).

Common situations: Rolling-writer jobs where the current output file is accidentally included in the concat list; empty part files produced by failed map/reduce tasks; compaction globs that match marker/zero-byte files.

Related errors


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