apache/hadoop · error · AlreadyBeingCreatedException

Failed to {} {} for {} on {} because {} is already the curre

Error message

Failed to {} {} for {} on {} because {} is already the current lease holder.

What it means

In the startFile/recoverFileLease path for an under-construction file: when the requesting holder already owns the file's lease and force=false, re-acquisition is refused with AlreadyBeingCreatedException('<holder> is already the current lease holder.') — the client is trying to open for write a file it itself already has open.

Source

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

  boolean recoverLeaseInternal(RecoverLeaseOp op, INodesInPath iip,
      String src, String holder, String clientMachine, boolean force)
      throws IOException {
    assert hasWriteLock(RwLockMode.GLOBAL);
    INodeFile file = iip.getLastINode().asFile();
    if (file.isUnderConstruction()) {
      //
      // If the file is under construction , then it must be in our
      // leases. Find the appropriate lease record.
      //
      Lease lease = leaseManager.getLease(holder);

      if (!force && lease != null) {
        Lease leaseFile = leaseManager.getLease(file);
        if (leaseFile != null && leaseFile.equals(lease)) {
          // We found the lease for this file but the original
          // holder is trying to obtain it again.
          throw new AlreadyBeingCreatedException(
              op.getExceptionMessage(src, holder, clientMachine,
                  holder + " is already the current lease holder."));
        }
      }
      //
      // Find the original holder.
      //
      FileUnderConstructionFeature uc = file.getFileUnderConstructionFeature();
      String clientName = uc.getClientName();
      lease = leaseManager.getLease(clientName);
      if (lease == null) {
        throw new AlreadyBeingCreatedException(
            op.getExceptionMessage(src, holder, clientMachine,
                "the file is under construction but no leases found."));
      }
      if (force) {
        // close now: no need to wait for soft lease expiration and 
        // close only the file src

View on GitHub (pinned to 2add963021)

Solutions

  1. Enforce one writer per file: reuse the existing stream or close it before re-creating
  2. Use unique per-writer paths (part files keyed by attempt id) plus atomic rename at commit
  3. If the earlier writer is dead but its lease lingers, call DistributedFileSystem#recoverLease(path), wait for isFileClosed, then re-create

Example fix

// before: retried tasks create the same file with the same client name
fs.create(outPath, true);   // AlreadyBeingCreatedException
// after: write private, commit by rename
Path tmp = new Path(outPath.getParent(), ".tmp/" + attemptId + "." + outPath.getName());
try (FSDataOutputStream out = fs.create(tmp, true)) { /* write */ }
fs.rename(tmp, outPath);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!((DistributedFileSystem) fs).isFileClosed(path)) {
  // something (possibly this client) still holds a lease: reuse, recover, or pick a new path
}

Try / catch

catch (AlreadyBeingCreatedException e) { if (e.getMessage() != null && e.getMessage().contains("already the current lease holder")) { closePriorStream(); retryCreate(); } else throw e; }

Prevention

When it happens

Trigger: The same clientName (DFSClient identity) calls create() on a path it currently holds a lease for without closing the first stream: duplicate job instance, task retry reusing the job's client name, or two threads in one JVM sharing a DFSClient and the same path.

Common situations: Speculative or retried tasks re-creating the same output file; apps that pin the DFS client name for idempotency and then run two writers; a service restarted in place re-creating its output path while the old handle is still open.

Related errors


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