apache/hadoop · warning · ReplicaAlreadyExistsException

Replica {replicaInfo} already exists on storage {targetStora

Error message

Replica {replicaInfo} already exists on storage {targetStorageType}

What it means

Thrown as ReplicaAlreadyExistsException from FsDatasetImpl.moveBlockAcrossStorage when replicaInfo.getVolume().getStorageType() already equals targetStorageType. The move request is a no-op: the replica lives on the requested storage tier already. It is a distinct exception type so callers (mover/NameNode block scheduler) can treat 'already satisfied' differently from real failures.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/fsdataset/impl/FsDatasetImpl.java:1097

   * @return Returns the Old replicaInfo
   * @throws IOException
   */
  @Override
  public ReplicaInfo moveBlockAcrossStorage(ExtendedBlock block,
      StorageType targetStorageType, String targetStorageId)
      throws IOException {
    ReplicaInfo replicaInfo = getReplicaInfo(block);
    if (replicaInfo.getState() != ReplicaState.FINALIZED) {
      throw new ReplicaNotFoundException(
          ReplicaNotFoundException.UNFINALIZED_REPLICA + block);
    }
    if (replicaInfo.getNumBytes() != block.getNumBytes()) {
      throw new IOException("Corrupted replica " + replicaInfo
          + " with a length of " + replicaInfo.getNumBytes()
          + " expected length is " + block.getNumBytes());
    }
    if (replicaInfo.getVolume().getStorageType() == targetStorageType) {
      throw new ReplicaAlreadyExistsException("Replica " + replicaInfo
          + " already exists on storage " + targetStorageType);
    }

    if (replicaInfo.isOnTransientStorage()) {
      // Block movement from RAM_DISK will be done by LazyPersist mechanism
      throw new IOException("Replica " + replicaInfo
          + " cannot be moved from storageType : "
          + replicaInfo.getVolume().getStorageType());
    }

    FsVolumeReference volumeRef = null;
    boolean shouldConsiderSameMountVolume =
        shouldConsiderSameMountVolume(replicaInfo.getVolume(),
            targetStorageType, targetStorageId);
    boolean useVolumeOnSameMount = false;

    try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
        block.getBlockPoolId())) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Treat as success/no-op: catch ReplicaAlreadyExistsException in the caller and skip — do not count it as a move failure.
  2. Ensure only one mover runs per cluster/path at a time (Mover CLI coordination).
  3. Verify the block's actual placement with hdfs fsck -blocks -locations — if it already matches policy, the move queue is stale.
  4. No remediation on the replica itself is needed; nothing is wrong with the data.

Example fix

// before: treating every exception from move as fatal
try {
  dataset.moveBlockAcrossStorage(block, StorageType.SSD, null);
} catch (IOException e) {
  LOG.error("move failed", e);
}

// after: no-op case handled explicitly
try {
  dataset.moveBlockAcrossStorage(block, StorageType.SSD, null);
} catch (ReplicaAlreadyExistsException e) {
  LOG.debug("Replica already on target storage type: {}", block);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip the call entirely when the replica is already on target tier.
ReplicaInfo info = fsDataset.getReplica(
    block.getBlockPoolId(), block.getBlockId());
if (info != null
    && info.getVolume().getStorageType() == targetStorageType) {
  return info; // no-op: already satisfied
}

Try / catch

// ReplicaAlreadyExistsException is the explicit no-op signal: absorb it.
try {
  fsDataset.moveBlockAcrossStorage(block, StorageType.DISK, null);
} catch (ReplicaAlreadyExistsException e) {
  LOG.debug("{} already on {}; nothing to do", block, StorageType.DISK);
  return; // success-equivalent
}

Prevention

When it happens

Trigger: Calling FsDatasetSpi.moveBlockAcrossStorage with a target type equal to the replica's current volume type — e.g. mover scheduling the same block twice, or a policy transition where the replica was already migrated by an earlier pass (or was written on the right tier to begin with).

Common situations: Concurrent mover instances; NameNode re-issuing satisfied moves after a DN re-registration; policy changed back and forth (HOT→COLD→HOT); duplicate scheduling during block-scheduler iterations.

Related errors


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