apache/hadoop · error · IllegalArgumentException
Invalid state for recovering from replica with blk id {}
Error message
Invalid state for recovering from replica with blk id {} What it means
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.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/ReplicaBuilder.java:300
throw new IllegalArgumentException("Incompatible fromReplica "
+ "state: " + fromReplica.getState());
} else {
if (null != block) {
return new ReplicaWaitingToBeRecovered(block, volume, directoryUsed);
} else {
return new ReplicaWaitingToBeRecovered(blockId, length, genStamp,
volume, directoryUsed);
}
}
}
private LocalReplica buildRUR() throws IllegalArgumentException {
if (null == fromReplica) {
throw new IllegalArgumentException(
"Missing a valid replica to recover from");
}
if (null != writer || null != block) {
throw new IllegalArgumentException("Invalid state for "
+ "recovering from replica with blk id "
+ fromReplica.getBlockId());
}
if (fromReplica.getState() == ReplicaState.RUR) {
return new ReplicaUnderRecovery((ReplicaUnderRecovery) fromReplica);
} else {
return new ReplicaUnderRecovery(fromReplica, recoveryId);
}
}
private ProvidedReplica buildProvidedFinalizedReplica()
throws IllegalArgumentException {
ProvidedReplica info = null;
if (fromReplica != null) {
throw new IllegalArgumentException("Finalized PROVIDED replica " +
"cannot be constructed from another replica");
}
if (fileRegion == null && uri == null &&View on GitHub (pinned to 2add963021)
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.
Example fix
// before
ReplicaUnderRecovery rur = (ReplicaUnderRecovery) new ReplicaBuilder(ReplicaState.RUR)
.setBlock(block)
.setWriterThread(writer)
.from(source)
.setRecoveryId(recoveryId).build();
// after
ReplicaUnderRecovery rur = (ReplicaUnderRecovery) new ReplicaBuilder(ReplicaState.RUR)
.from(source)
.setRecoveryId(recoveryId).build(); Defensive patterns
Strategy: validation
Validate before calling
Preconditions.checkState(writer == null && block == null,
"RUR construction accepts only from() + setRecoveryId()");
ReplicaUnderRecovery rur = (ReplicaUnderRecovery) new ReplicaBuilder(ReplicaState.RUR)
.from(source)
.setRecoveryId(recoveryId).build(); Try / catch
try {
rur = (ReplicaUnderRecovery) builder.build();
} catch (IllegalArgumentException e) {
throw new IOException("RUR setup failed for block " + source.getBlockId()
+ ": " + e.getMessage(), e);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Missing a valid replica to recover from
- Unknown replica state {}
- Incompatible fromReplica state: {}
- A valid writer is required for constructing a RBW from block
- A valid writer is required for constructing a Replica from b
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/70e73e8801f2b380.
Report an issue: GitHub.