apache/hadoop · error · UnsupportedOperationException

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

Error message

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

What it means

Recovery IDs are bookkeeping that exists only on replicas under recovery; a FINALIZED FinalizedReplica never entered a recovery session, so getRecoveryID() throws UnsupportedOperationException. Seeing it means recovery logic reached a finalized replica without a state check.

Source

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

  @Override  // Object
  public int hashCode() {
    return super.hashCode();
  }
  
  @Override
  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) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Check replica.getState()/type before reading the recovery ID; only RUR/RBW/RWR replicas carry one.
  2. Route recovery through ReplicaUnderReconstruction references obtained from the replicasBeingWritten map rather than raw volume-map scans.
  3. Add regression tests covering finalized replicas in the affected flow.
  4. If framework code is at fault, verify against the corresponding Hadoop JIRA and upgrade.

Example fix

// before
long id = replica.getRecoveryID();

// after
if (replica.getState() != ReplicaState.FINALIZED) {
  long id = replica.getRecoveryID();
}
Defensive patterns

Strategy: type-guard

Type guard

static boolean hasRecoveryId(ReplicaInfo r) {
  ReplicaState s = r.getState();
  return s == ReplicaState.RBW || s == ReplicaState.RWR || s == ReplicaState.RUR;
}

Try / catch

try {
  long id = replica.getRecoveryID();
} catch (UnsupportedOperationException e) {
  // FINALIZED replica has no recovery ID: fix the caller's replica selection
}

Prevention

When it happens

Trigger: Calling getRecoveryID() on a replica with state FINALIZED: recovery or truncate code paths that enumerate all replicas and read recovery IDs, or custom logic that assumes getRecoveryID() is universally implemented.

Common situations: Custom block-recovery implementations; tests that exercise every replica in the volume map; refactored recovery flows where a state filter was dropped.

Related errors


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