apache/hadoop · error · UnsupportedOperationException

Replica of type {} does not support getRecoveryID

Error message

Replica of type {} does not support getRecoveryID

What it means

ReplicaWaitingToBeRecovered.getRecoveryID() throws UnsupportedOperationException: an RWR replica carries no recovery id. Recovery ids exist only while a replica is actively under recovery (ReplicaUnderRecovery), which is a different state from merely waiting to be recovered after its writer died.

Source

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

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

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

View on GitHub (pinned to 2add963021)

Solutions

  1. Only call getRecoveryID() when replica.getState() == ReplicaState.RUR (or instanceof ReplicaUnderRecovery)
  2. Return a sentinel (e.g., 0) in generic code paths for non-RUR replicas
  3. Fix the caller: waiting-to-be-recovered replicas must first be wrapped in ReplicaUnderRecovery to gain a recovery id

Example fix

// before
long id = replica.getRecoveryID(); // throws for RWR

// after
long id = (replica instanceof ReplicaUnderRecovery)
    ? ((ReplicaUnderRecovery) replica).getRecoveryID()
    : 0L;
Defensive patterns

Strategy: type-guard

Validate before calling

long recoveryIdOrZero(ReplicaInfo r) { return (r instanceof ReplicaUnderRecovery) ? r.getRecoveryID() : 0L; }

Type guard

static boolean exposesRecoveryId(ReplicaInfo r) {
  return r instanceof ReplicaUnderRecovery;
}

Try / catch

try { id = r.getRecoveryID(); } catch (UnsupportedOperationException e) { id = 0L; /* caller treats 0 as 'not under recovery' */ }

Prevention

When it happens

Trigger: Invoking getRecoveryID() on a ReplicaWaitingToBeRecovered instance - typically from generic recovery/monitoring code (metrics collectors, block scanners, tests) that walks the volume map and unconditionally reads recovery metadata.

Common situations: Block recovery tooling or tests that treat every replica in the volume map uniformly; code written against ReplicaUnderRecovery being handed an RWR replica after a recovery handshake aborts.

Related errors


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