apache/hadoop · error · UnsupportedOperationException

Replica of type ${getState()} does not support setRecoveryID

Error message

Replica of type ${getState()} does not support setRecoveryID

What it means

setRecoveryID() stores the ID assigned at the start of a recovery session; a FINALIZED FinalizedReplica is not part of any recovery session and refuses the mutation with UnsupportedOperationException. This is a state-machine violation by the caller, not a runtime condition to retry.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/FinalizedReplica.java:138

  public String toString() {
    return super.toString();
  }

  @Override
  public ReplicaInfo getOriginalReplica() {
    throw new UnsupportedOperationException("Replica of type " + getState() +
        " does not support getOriginalReplica");
  }

  @Override
  public long getRecoveryID() {
    throw new UnsupportedOperationException("Replica of type " + getState() +
        " does not support getRecoveryID");
  }

  @Override
  public void setRecoveryID(long recoveryId) {
    throw new UnsupportedOperationException("Replica of type " + getState() +
        " does not support setRecoveryID");
  }

  @Override
  public ReplicaRecoveryInfo createInfo() {
    throw new UnsupportedOperationException("Replica of type " + getState() +
        " does not support createInfo");
  }

  @Override
  public long getMetadataLength() {
    if (metaLength < 0) {
      metaLength = (int)super.getMetadataLength();
    }
    return metaLength;
  }

  public byte[] getLastPartialChunkChecksum() {

View on GitHub (pinned to 2add963021)

Solutions

  1. Guard the call with a state check and only set recovery IDs on RUR/RBW/RWR replicas.
  2. Review the surrounding recovery flow: a finalized replica being pulled into recovery usually signals the wrong replica was selected.
  3. Add unit coverage for the finalized-replica case.
  4. Upgrade if the unguarded call site is in released framework code.

Example fix

// before
replica.setRecoveryID(newId);

// after
if (replica instanceof ReplicaUnderReconstruction) {
  replica.setRecoveryID(newId);
}
Defensive patterns

Strategy: type-guard

Type guard

static boolean canSetRecoveryId(ReplicaInfo r) {
  return r instanceof ReplicaUnderReconstruction;
}

Try / catch

try {
  replica.setRecoveryID(newId);
} catch (UnsupportedOperationException e) {
  // FINALIZED replica pulled into recovery: wrong replica selected — fix caller logic
}

Prevention

When it happens

Trigger: Recovery code calling setRecoveryID(id) on a replica whose state is FINALIZED — typically a missing state filter before mutating recovery bookkeeping.

Common situations: Custom truncate/append handling; patched recovery flows; tooling that resets recovery IDs on all replicas.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/9ea252d122203354. Report an issue: GitHub.