{"record":{"id":"317419c63aee263a","repo":"apache/hadoop","slug":"trying-to-remove-more-than-one-block-from-file","errorCode":null,"errorMessage":"Trying to remove more than one block from file {}","messagePattern":"Trying to remove more than one block from file (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java","lineNumber":1182,"sourceCode":"        changeMade = true;\n        fsNamesys.getBlockManager().forceCompleteBlock(oldBlock);\n      }\n      if (changeMade) {\n        // The state or gen-stamp of the block has changed. So, we may be\n        // able to process some messages from datanodes that we previously\n        // were unable to process.\n        fsNamesys.getBlockManager().processQueuedMessagesForBlock(newBlock);\n      }\n    }\n    \n    if (newBlocks.length < oldBlocks.length) {\n      // We're removing a block from the file, e.g. abandonBlock(...)\n      if (!file.isUnderConstruction()) {\n        throw new IOException(\"Trying to remove a block from file \" +\n            path + \" which is not under construction.\");\n      }\n      if (newBlocks.length != oldBlocks.length - 1) {\n        throw new IOException(\"Trying to remove more than one block from file \"\n            + path);\n      }\n      Block oldBlock = oldBlocks[oldBlocks.length - 1];\n      boolean removed = FSDirWriteFileOp.unprotectedRemoveBlock(\n          fsDir, path, iip, file, oldBlock);\n      if (!removed && !(op instanceof UpdateBlocksOp)) {\n        throw new IOException(\"Trying to delete non-existant block \" + oldBlock);\n      }\n    } else if (newBlocks.length > oldBlocks.length) {\n      final boolean isStriped = ecPolicy != null;\n      // We're adding blocks\n      for (int i = oldBlocks.length; i < newBlocks.length; i++) {\n        Block newBlock = newBlocks[i];\n        final BlockInfo newBI;\n        if (!op.shouldCompleteLastBlock()) {\n          // TODO: shouldn't this only be true for the last block?\n          // what about an old-version fsync() where fsync isn't called\n          // until several blocks in?","sourceCodeStart":1164,"sourceCodeEnd":1200,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java#L1164-L1200","documentation":"updateBlocks accepts at most one block removal per op, because abandonBlock removes exactly the last block. If newBlocks.length is less than oldBlocks.length minus one, replay throws IOException('Trying to remove more than one block from file <path>'). No valid client operation produces such a list, so the record is corrupt or the replay state is misaligned.","triggerScenarios":"A block-list update that drops two or more blocks in one op: corrupted op payload, duplicate replay shifting the lists, or logs from a faulty writer.","commonSituations":"Corrupt segments after crashes; hand-patched logs; replay against mismatched image state.","solutions":["Run 'hdfs namenode -recover' to skip the bad transaction","Restore a consistent fsimage plus edits from one backup","Trace the file's ops with 'hdfs oev' to see the sequence that produced the multi-block drop"],"exampleFix":"# before: NameNode aborts during replay\nhdfs --daemon start namenode\n\n# after: locate and skip the corrupt op\nhdfs oev -i <segment> -o /tmp/edits.xml -p xml\ngrep -n 'SET_BLOCKS\\|path=/data/x' /tmp/edits.xml | tail\nhdfs namenode -recover","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  loader.loadFSEdits(storage, 0);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"remove more than one block\")) {\n    // impossible record for valid writers: treat the segment as corrupt and\n    // recover or restore from backup\n  }\n  throw e;\n}","preventionTips":["Do not patch or regenerate edit logs with external tools","Verify segment integrity with 'hdfs oev' after any manual journal surgery"],"tags":["hdfs","namenode","edit-log","replay","blocks","abandon-block","corruption"],"backgroundTag":"edit-log-replay-inconsistency","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}