apache/hadoop · error · IllegalArgumentException

Unknown replica state {} for PROVIDED replica

Error message

Unknown replica state {} for PROVIDED replica

What it means

When ReplicaBuilder.build() targets a volume whose StorageType is PROVIDED, it delegates to buildProvidedReplica(), which only supports ReplicaState.FINALIZED. Any of RWR, RUR, RBW, TEMPORARY (or a state added later that hits default) throws IllegalArgumentException because provided replicas are immutable references into an external filesystem - they can never be in a write pipeline or under recovery on the DataNode.

Source

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

    } else {
      info = new FinalizedProvidedReplica(fileRegion, volume, conf, remoteFS);
    }
    return info;
  }

  private ProvidedReplica buildProvidedReplica()
      throws IllegalArgumentException {
    ProvidedReplica info = null;
    switch(this.state) {
    case FINALIZED:
      info = buildProvidedFinalizedReplica();
      break;
    case RWR:
    case RUR:
    case RBW:
    case TEMPORARY:
    default:
      throw new IllegalArgumentException("Unknown replica state " +
          state + " for PROVIDED replica");
    }
    return info;
  }

  private LocalReplica buildLocalReplica()
      throws IllegalArgumentException {
    LocalReplica info = null;
    switch(this.state) {
    case FINALIZED:
      info = buildFinalizedReplica();
      break;
    case RWR:
      info = buildRWR();
      break;
    case RUR:
      info = buildRUR();
      break;

View on GitHub (pinned to 2add963021)

Solutions

  1. Use ReplicaState.FINALIZED whenever the target volume is a PROVIDED volume
  2. Branch on volume.getStorageType() before building: only call the builder with non-FINALIZED states for local (DISK/ARCHIVE etc.) volumes
  3. If a write pipeline genuinely needs storage, move the replica to a local volume instead of PROVIDED

Example fix

// before
ReplicaInfo r = new ReplicaBuilder(ReplicaState.RBW)
    .setFsVolume(providedVolume).build(); // throws for PROVIDED

// after
ReplicaInfo r;
if (volume.getStorageType() == StorageType.PROVIDED) {
  r = new ReplicaBuilder(ReplicaState.FINALIZED)
      .setFsVolume(volume).setFileRegion(region).build();
} else {
  r = new ReplicaBuilder(ReplicaState.RBW).setFsVolume(volume).build();
}
Defensive patterns

Strategy: validation

Validate before calling

if (volume.getStorageType() == StorageType.PROVIDED
    && state != ReplicaState.FINALIZED) {
  throw new IllegalStateException(
      "PROVIDED volume only supports FINALIZED replicas, got " + state);
}
ReplicaInfo r = new ReplicaBuilder(state).setFsVolume(volume).build();

Type guard

static boolean isProvided(FsVolumeSpi v) {
  return v != null && v.getStorageType() == StorageType.PROVIDED;
}

Try / catch

try { builder.build(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("for PROVIDED replica")) { state = ReplicaState.FINALIZED; /* rebuild */ } else throw e; }

Prevention

When it happens

Trigger: new ReplicaBuilder(ReplicaState.RBW) (or RWR/RUR/TEMPORARY) followed by .setFsVolume(volume) where volume.getStorageType()==StorageType.PROVIDED, then .build(). The switch in buildProvidedReplica() falls through to the default branch and throws.

Common situations: Generic replica-handling code that was written for local disks being reused unchanged on a PROVIDED volume (e.g., block recovery or RBW append paths hitting provided storage); tests that build replicas in RBW state against a ProvidedVolume; misconfigured dfs.datanode.data.dir mixing PROVIDED with write workloads that expect local replicas.

Related errors


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