{"record":{"id":"714e7f8cbb9736ea","repo":"apache/hadoop","slug":"update-but-the-new-block-does-not-have-a-lar","errorCode":null,"errorMessage":"Update {} but the new block {} does not have a larger generation stamp than the last block {}","messagePattern":"Update (.+?) but the new block (.+?) does not have a larger generation stamp than the last block (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java","lineNumber":6201,"sourceCode":"\n  private void updatePipelineInternal(String clientName, ExtendedBlock oldBlock,\n      ExtendedBlock newBlock, DatanodeID[] newNodes, String[] newStorageIDs,\n      boolean logRetryCache)\n      throws IOException {\n    assert hasWriteLock(RwLockMode.GLOBAL);\n    // check the vadility of the block and lease holder name\n    final INodeFile pendingFile = checkUCBlock(oldBlock, clientName);\n    final String src = pendingFile.getFullPathName();\n    final BlockInfo lastBlock = pendingFile.getLastBlock();\n    assert !lastBlock.isComplete();\n\n    // check new GS & length: this is not expected\n    if (newBlock.getGenerationStamp() <= lastBlock.getGenerationStamp()) {\n      final String msg = \"Update \" + oldBlock + \" but the new block \" + newBlock\n          + \" does not have a larger generation stamp than the last block \"\n          + lastBlock;\n      LOG.warn(msg);\n      throw new IOException(msg);\n    }\n    if (newBlock.getNumBytes() < lastBlock.getNumBytes()) {\n      final String msg = \"Update \" + oldBlock + \" (size=\"\n          + oldBlock.getNumBytes() + \") to a smaller size block \" + newBlock\n          + \" (size=\" + newBlock.getNumBytes() + \")\";\n      LOG.warn(msg);\n      throw new IOException(msg);\n    }\n\n    // Update old block with the new generation stamp and new length\n    blockManager.updateLastBlock(lastBlock, newBlock);\n\n    // find the DatanodeDescriptor objects\n    final DatanodeStorageInfo[] storages = blockManager.getDatanodeManager()\n        .getDatanodeStorageInfos(newNodes, newStorageIDs,\n            \"src=%s, oldBlock=%s, newBlock=%s, clientName=%s\",\n            src, oldBlock, newBlock, clientName);\n    lastBlock.getUnderConstructionFeature().setExpectedLocations(lastBlock,","sourceCodeStart":6183,"sourceCodeEnd":6219,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java#L6183-L6219","documentation":"updateBlock enforces generation-stamp monotonicity: the replacement block's GS must be strictly greater than the last block's current GS. A smaller or equal GS means the caller is applying stale recovery metadata, so the update is rejected with an IOException after a warn log.","triggerScenarios":"Retrying updateBlock with a previously generated stamp after another recovery already advanced the block's GS; two concurrent recoveries computing updates off the same base state.","commonSituations":"Timeout-retry logic that reuses the old newBlock; races between a client and a lease-recovery thread updating the same last block.","solutions":["Re-fetch the current last block (getBlockLocations / ExtendedBlock) and build the update from its latest GS","Ensure one recovery driver per block at a time","Treat the error as 'state moved on': verify final state instead of blind retry"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  updateBlock(oldBlock, newBlock, ...);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"does not have a larger generation stamp\")) {\n    LocatedBlock cur = dfs.getClient().getLastLocatedBlock(path);\n    ExtendedBlock fixed = new ExtendedBlock(cur.getBlock().getBlockPoolId(),\n        cur.getBlock().getBlockId(), newLen, cur.getBlock().getGenerationStamp() + 1);\n    updateBlock(cur.getBlock(), fixed, ...); // rebuild from current GS\n  } else { throw e; }\n}","preventionTips":["Derive the new GS from the block's current GS, never from a cached value","Single driver per block recovery to avoid concurrent GS bumps"],"tags":["hdfs","namenode","generation-stamp","pipeline-recovery","monotonicity"],"backgroundTag":"generation-stamp-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}