{"record":{"id":"70e73e8801f2b380","repo":"apache/hadoop","slug":"invalid-state-for-recovering-from-replica-with-blk","errorCode":null,"errorMessage":"Invalid state for recovering from replica with blk id {}","messagePattern":"Invalid state for recovering from replica with blk id (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ReplicaBuilder.java","lineNumber":300,"sourceCode":"      throw new IllegalArgumentException(\"Incompatible fromReplica \"\n          + \"state: \" + fromReplica.getState());\n    } else {\n      if (null != block) {\n        return new ReplicaWaitingToBeRecovered(block, volume, directoryUsed);\n      } else {\n        return new ReplicaWaitingToBeRecovered(blockId, length, genStamp,\n            volume, directoryUsed);\n      }\n    }\n  }\n\n  private LocalReplica buildRUR() throws IllegalArgumentException {\n    if (null == fromReplica) {\n      throw new IllegalArgumentException(\n          \"Missing a valid replica to recover from\");\n    }\n    if (null != writer || null != block) {\n      throw new IllegalArgumentException(\"Invalid state for \"\n          + \"recovering from replica with blk id \"\n          + fromReplica.getBlockId());\n    }\n    if (fromReplica.getState() == ReplicaState.RUR) {\n      return new ReplicaUnderRecovery((ReplicaUnderRecovery) fromReplica);\n    } else {\n      return new ReplicaUnderRecovery(fromReplica, recoveryId);\n    }\n  }\n\n  private ProvidedReplica buildProvidedFinalizedReplica()\n      throws IllegalArgumentException {\n    ProvidedReplica info = null;\n    if (fromReplica != null) {\n      throw new IllegalArgumentException(\"Finalized PROVIDED replica \" +\n          \"cannot be constructed from another replica\");\n    }\n    if (fileRegion == null && uri == null &&","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ReplicaBuilder.java#L282-L318","documentation":"ReplicaBuilder.buildRUR() throws IllegalArgumentException 'Invalid state for recovering from replica' when the builder was configured with a writer thread (setWriterThread) or a Block (setBlock) in addition to from(replica). Recovery wraps an existing replica; writer/block are write-path inputs that contradict recovery semantics.","triggerScenarios":"new ReplicaBuilder(ReplicaState.RUR).from(source).setWriterThread(t).build() or the same with .setBlock(block) - i.e. copy-pasted builder chains from RBW/TEMPORARY construction reused for the RUR path.","commonSituations":"Shared builder helper methods that 'set everything' (block, writer, recoveryId) regardless of target state; test fixtures that configure one generic builder and reuse it for multiple states including RUR.","solutions":["For RUR, set only from(replica) and setRecoveryId(long); remove setWriterThread/setBlock from the chain.","Split per-state builder factories so each state sets exactly its own inputs.","Add a precondition in your wrapper: writer == null && block == null when building RUR."],"exampleFix":"// before\nReplicaUnderRecovery rur = (ReplicaUnderRecovery) new ReplicaBuilder(ReplicaState.RUR)\n    .setBlock(block)\n    .setWriterThread(writer)\n    .from(source)\n    .setRecoveryId(recoveryId).build();\n\n// after\nReplicaUnderRecovery rur = (ReplicaUnderRecovery) new ReplicaBuilder(ReplicaState.RUR)\n    .from(source)\n    .setRecoveryId(recoveryId).build();","handlingStrategy":"validation","validationCode":"Preconditions.checkState(writer == null && block == null,\n    \"RUR construction accepts only from() + setRecoveryId()\");\nReplicaUnderRecovery rur = (ReplicaUnderRecovery) new ReplicaBuilder(ReplicaState.RUR)\n    .from(source)\n    .setRecoveryId(recoveryId).build();","typeGuard":null,"tryCatchPattern":"try {\n  rur = (ReplicaUnderRecovery) builder.build();\n} catch (IllegalArgumentException e) {\n  throw new IOException(\"RUR setup failed for block \" + source.getBlockId()\n      + \": \" + e.getMessage(), e);\n}","preventionTips":["Use a dedicated builder chain per replica state; never share a generic 'set everything' chain.","RUR takes only from(replica) and setRecoveryId(long).","Reset writer/block references before reusing a builder instance for recovery."],"tags":["hdfs","datanode","replica","builder","block-recovery","conflicting-arguments"],"backgroundTag":"builder-conflicting-arguments","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}