apache/hadoop · error · IOException
Cannot allocate block in <src>: passed 'previous' block <pre
Error message
Cannot allocate block in <src>: passed 'previous' block <previous> does not match actual last block in file <lastBlockInFile>
What it means
addBlock requires the client's previous block to match either the completed penultimate block (fresh allocation, case 1) or the penultimate block for a retry (case 2). When it matches neither, the client's view of the file tail and the NameNode's have diverged (another writer appended, lease recovery rebuilt the tail, or state went stale across failover) and case 3 throws IOException.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirWriteFileOp.java:682
"Request looked like a retry to allocate block " +
lastBlockInFile + " but it already contains " +
lastBlockInFile.getNumBytes() + " bytes");
}
// Case 2
// Return the last block.
NameNode.stateChangeLog.info("BLOCK* allocateBlock: caught retry for " +
"allocation of a new block in " + src + ". Returning previously" +
" allocated block " + lastBlockInFile);
long offset = file.computeFileSize();
BlockUnderConstructionFeature uc =
lastBlockInFile.getUnderConstructionFeature();
onRetryBlock[0] = makeLocatedBlock(fsn, lastBlockInFile,
uc.getExpectedStorageLocations(), offset);
return new FileState(file, src, iip);
} else {
// Case 3
throw new IOException("Cannot allocate block in " + src + ": " +
"passed 'previous' block " + previous + " does not match actual " +
"last block in file " + lastBlockInFile);
}
}
return new FileState(file, src, iip);
}
static boolean completeFile(FSNamesystem fsn, FSPermissionChecker pc,
final String srcArg, String holder, ExtendedBlock last, long fileId)
throws IOException {
String src = srcArg;
if (NameNode.stateChangeLog.isDebugEnabled()) {
NameNode.stateChangeLog.debug("DIR* NameSystem.completeFile: " +
src + " for " + holder);
}
checkBlock(fsn, last);
INodesInPath iip = fsn.dir.resolvePath(pc, src, fileId);
return completeFileInternal(fsn, iip, holder,View on GitHub (pinned to 2add963021)
Solutions
- Close and reopen the writer: fs.append(path) re-reads the authoritative tail, then continue from there
- Enforce one writer per file; lease recovery transfers ownership, it does not merge concurrent tails
- On HA failover let DFSClient rebuild state instead of caching LocatedBlocks manually
Example fix
// before: stale cached block drives the next allocation
namenode.addBlock(src, clientName, cachedPrevious, fileId, null, 0); // throws
// after: refresh state by reopening for append
try (FSDataOutputStream out = fs.append(path)) {
out.write(payload);
} Defensive patterns
Strategy: try-catch
Validate before calling
// before allocating the next block, confirm the tail still matches your view
BlockStatuses tail = namenode.getFileBlockList(src); // custom ClientProtocol only
if (!matches(previous, tail)) {
previous = refreshFrom(tail);
} Try / catch
try {
lb = namenode.addBlock(src, clientName, previous, fileId, null, 0);
} catch (IOException e) { // "does not match actual last block"
// stale view of the tail: reopen for append and continue
try (FSDataOutputStream out = fs.append(path)) {
out.write(payload);
}
} Prevention
- One writer per file at a time; lease recovery does not merge concurrent tails
- After HA failover, reopen streams instead of reusing cached block lists
- Custom ClientProtocol clients must refresh file state before addBlock
When it happens
Trigger: addBlock(previous=X) where X is neither the current last block nor the penultimate: writing after another client appended under a recovered lease, or a long-lived client using cached block lists after HA failover or lease preemption.
Common situations: Two writers on one file after lease steal; custom ClientProtocol clients caching block state; clients surviving NameNode failover without refreshing file state.
Related errors
- Replica was found but missing fields.
- Trying to commit inconsistent block: id = {blockId}, expecte
- Commit block with mismatching GS. NN has {block}, client sub
- Commit or complete block {commitBlock}, whereas it is under
- Cannot complete block: block has not been COMMITTED by the c
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/5244ad89ba10ed52.
Report an issue: GitHub.