apache/hadoop · error · UnsupportedOperationException

setShuffleFinishTime() not supported for MapTask

Error message

setShuffleFinishTime() not supported for MapTask

What it means

MapTaskStatus rejects setShuffleFinishTime() with UnsupportedOperationException because a map task has no shuffle phase; only ReduceTaskStatus accepts shuffle timestamps (the framework sets them as the copy phase completes). Writing shuffle timing into a map status is an API misuse, and the guard makes it loud.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/MapTaskStatus.java:64

   * @param finishTime finish time of task.
   */
  @Override
  void setFinishTime(long finishTime) {
    super.setFinishTime(finishTime);
    // set mapFinishTime if it hasn't been set before
    if (getMapFinishTime() == 0) {
      setMapFinishTime(finishTime);
    }
  }
  
  @Override
  public long getShuffleFinishTime() {
    throw new UnsupportedOperationException("getShuffleFinishTime() not supported for MapTask");
  }

  @Override
  void setShuffleFinishTime(long shuffleFinishTime) {
    throw new UnsupportedOperationException("setShuffleFinishTime() not supported for MapTask");
  }

  @Override
  public long getMapFinishTime() {
    return mapFinishTime;
  }
  
  @Override
  void setMapFinishTime(long mapFinishTime) {
    this.mapFinishTime = mapFinishTime;
  }
  
  @Override
  synchronized void statusUpdate(TaskStatus status) {
    super.statusUpdate(status);
    
    if (status.getMapFinishTime() != 0) {
      this.mapFinishTime = status.getMapFinishTime();

View on GitHub (pinned to 2add963021)

Solutions

  1. Guard with instanceof ReduceTaskStatus (or !status.getIsMap()) before calling shuffle setters
  2. Apply only map-relevant fields (finishTime, mapFinishTime, state, progress) to MapTaskStatus
  3. Centralize status copying in one adapter that knows both shapes instead of blanket setter loops

Example fix

// before
copy.setShuffleFinishTime(src.getShuffleFinishTime()); // throws when copy is a MapTaskStatus

// after
if (copy instanceof ReduceTaskStatus && src instanceof ReduceTaskStatus) {
  ((ReduceTaskStatus) copy).setShuffleFinishTime(((ReduceTaskStatus) src).getShuffleFinishTime());
}
Defensive patterns

Strategy: type-guard

Type guard

static boolean acceptsShuffleTimestamps(TaskStatus s) {
  return s instanceof ReduceTaskStatus;
}

Try / catch

if (acceptsShuffleTimestamps(copy)) { copy.setShuffleFinishTime(ts); } // guard before setter; a caught UnsupportedOperationException here means a type-handling bug, fix the caller

Prevention

When it happens

Trigger: Framework or tooling code copying timestamps across TaskStatus instances calls setShuffleFinishTime on a MapTaskStatus: history-replay tools applying every setter, custom AM code mirroring statuses between layers, unit tests constructing statuses generically.

Common situations: Job-history replay/audit utilities; custom ApplicationMaster status mirroring; shared helpers that hydrate TaskStatus fields from serialized maps.

Related errors


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