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() assigns the per-recovery ID used during block synchronization; it is meaningful only for replicas under recovery. FinalizedProvidedReplica is FINALIZED and provided (bytes in external storage), so it has no recovery state to mutate and throws UnsupportedOperationException.

Source

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

  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");
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Filter to recovery-state replicas (RBW/RWR/RUR) before assigning recovery IDs.
  2. Recovery should target a replica that actually tracks recovery state; exclude provided replicas from the candidate set.
  3. Upgrade HDFS if the call site is framework code — check the version's provided-storage fixes.
  4. In custom code paths, assert the replica state before mutating recovery bookkeeping.

Example fix

// before
replica.setRecoveryID(recoveryId);

// after: only mutate replicas that track recovery
if (replica instanceof ReplicaUnderReconstruction) {
  replica.setRecoveryID(recoveryId);
}
Defensive patterns

Strategy: type-guard

Type guard

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

Try / catch

try {
  replica.setRecoveryID(recoveryId);
} catch (UnsupportedOperationException e) {
  // replica cannot join a recovery session: exclude it from the flow
}

Prevention

When it happens

Trigger: A recovery flow calling setRecoveryID(recoveryId) on a replica that is a FinalizedProvidedReplica — typically when the replica chosen for recovery on this DataNode is PROVIDED rather than a local RBW/RWR/RUR replica.

Common situations: PROVIDED-storage deployments where recovery logic does not filter replica types; custom truncate/append implementations that set recovery IDs on every replica they find; test harnesses exercising all replicas uniformly.

Related errors


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