apache/hadoop · error · IllegalArgumentException

A valid writer is required for constructing a Replica from b

Error message

A valid writer is required for constructing a Replica from block {}

What it means

When ReplicaBuilder constructs a LocalReplicaInPipeline (TEMPORARY) from a Block via setBlock, it requires a writer thread because in-pipeline replicas track the writing thread. A null writer (no setWriterThread call) triggers IllegalArgumentException 'A valid writer is required for constructing a Replica from block'.

Source

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

          return new ReplicaBeingWritten(blockId, genStamp, volume,
              directoryUsed, bytesToReserve);
        }
      }
    }
  }

  private LocalReplicaInPipeline buildTemporaryReplica()
      throws IllegalArgumentException {
    if (null != fromReplica &&
        fromReplica.getState() == ReplicaState.TEMPORARY) {
      return new LocalReplicaInPipeline((LocalReplicaInPipeline) fromReplica);
    } else if (null != fromReplica) {
      throw new IllegalArgumentException("Incompatible fromReplica "
          + "state: " + fromReplica.getState());
    } else {
      if (null != block) {
        if (null == writer) {
          throw new IllegalArgumentException("A valid writer is "
              + "required for constructing a Replica from block "
              + block.getBlockId());
        }
        return new LocalReplicaInPipeline(block, volume, directoryUsed,
            writer);
      } else {
        if (length != -1) {
          return new LocalReplicaInPipeline(blockId, length, genStamp,
              volume, directoryUsed, writer, bytesToReserve);
        } else {
          return new LocalReplicaInPipeline(blockId, genStamp, volume,
              directoryUsed, bytesToReserve);
        }
      }
    }
  }

  private LocalReplica buildFinalizedReplica() throws IllegalArgumentException {

View on GitHub (pinned to 2add963021)

Solutions

  1. Call .setWriterThread(Thread.currentThread()) before build when using setBlock.
  2. Or use the field-based constructors path (setBlockId/setGenerationStamp/.../setWriterThread) - writer is still mandatory for in-pipeline replicas.
  3. Add a builder wrapper that asserts writer != null when block != null.

Example fix

// before
LocalReplicaInPipeline r = new ReplicaBuilder(ReplicaState.TEMPORARY)
    .setBlock(block).buildLocalReplicaInPipeline();

// after
LocalReplicaInPipeline r = new ReplicaBuilder(ReplicaState.TEMPORARY)
    .setBlock(block)
    .setWriterThread(Thread.currentThread())
    .buildLocalReplicaInPipeline();
Defensive patterns

Strategy: validation

Validate before calling

LocalReplicaInPipeline r = new ReplicaBuilder(ReplicaState.TEMPORARY)
    .setBlock(block)
    .setWriterThread(Thread.currentThread())  // required with setBlock
    .buildLocalReplicaInPipeline();

Try / catch

try {
  r = builder.buildLocalReplicaInPipeline();
} catch (IllegalArgumentException e) {
  throw new IllegalArgumentException("TEMPORARY construction failed (missing writer): "
      + e.getMessage(), e);
}

Prevention

When it happens

Trigger: new ReplicaBuilder(ReplicaState.TEMPORARY).setBlock(block).buildLocalReplicaInPipeline() with no .setWriterThread(...) - the block branch of buildTemporaryReplica() finds writer == null and throws.

Common situations: Staging replicas for replication tests or DataNode restart flows where code was written for finalized replicas (which need no writer) and reused for TEMPORARY; builder chains where setWriterThread was accidentally dropped during refactoring.

Related errors


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