apache/hadoop · error · IOException

Invalid job run state : {runState}

Error message

Invalid job run state : {runState}

What it means

This bridge adapts the new org.apache.hadoop.mapreduce OutputCommitter.abortJob(JobContext, State) to the old mapred API. It maps the enum via JobStatus.getOldNewJobRunState and accepts only FAILED and KILLED - the two states for which aborting a job is meaningful. Aborting with RUNNING or SUCCEEDED is a lifecycle programming error and throws this IOException.

Source

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

   */
  @Override
  public final void commitJob(org.apache.hadoop.mapreduce.JobContext context
                             ) throws IOException {
    commitJob((JobContext) context);
  }
  
  /**
   * This method implements the new interface by calling the old method. Note
   * that the input types are different between the new and old apis and this
   * is a bridge between the two.
   */
  @Override
  public final void abortJob(org.apache.hadoop.mapreduce.JobContext context, 
		                   org.apache.hadoop.mapreduce.JobStatus.State runState) 
  throws IOException {
    int state = JobStatus.getOldNewJobRunState(runState);
    if (state != JobStatus.FAILED && state != JobStatus.KILLED) {
      throw new IOException ("Invalid job run state : " + runState.name());
    }
    abortJob((JobContext) context, state);
  }
  
  /**
   * This method implements the new interface by calling the old method. Note
   * that the input types are different between the new and old apis and this
   * is a bridge between the two.
   */
  @Override
  public final 
  void setupTask(org.apache.hadoop.mapreduce.TaskAttemptContext taskContext
                 ) throws IOException {
    setupTask((TaskAttemptContext) taskContext);
  }
  
  /**
   * This method implements the new interface by calling the old method. Note

View on GitHub (pinned to 2add963021)

Solutions

  1. Only invoke abortJob for FAILED/KILLED; call commitJob() on success and do nothing while RUNNING
  2. Guard the call site on the final job state before delegating
  3. When extending OutputCommitter, override the old-API abortJob(JobContext, int) - this final bridge enforces the state check for you

Example fix

// before
committer.abortJob(jobContext, finalState); // runs even when finalState == SUCCEEDED

// after
if (finalState == JobStatus.State.FAILED || finalState == JobStatus.State.KILLED) {
  committer.abortJob(jobContext, finalState);
} else if (finalState == JobStatus.State.SUCCEEDED) {
  committer.commitJob(jobContext);
}
Defensive patterns

Strategy: validation

Validate before calling

static boolean isAbortableState(org.apache.hadoop.mapreduce.JobStatus.State s) {
  return s == org.apache.hadoop.mapreduce.JobStatus.State.FAILED
      || s == org.apache.hadoop.mapreduce.JobStatus.State.KILLED;
}
// use: if (isAbortableState(finalState)) committer.abortJob(ctx, finalState);

Prevention

When it happens

Trigger: Calling committer.abortJob(ctx, JobStatus.State.SUCCEEDED) or State.RUNNING: unconditional cleanup blocks that abort regardless of outcome, AM state-machine bugs routing success through abort, or custom committers delegating to the bridge from a finally-style path.

Common situations: Custom committers wrapped around the old API; 'abort to be safe' cleanup code; MR1 code ported where abortJob(int) had been invoked with arbitrary states.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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