apache/hadoop · error · IOException

NoSuchUpload

NoSuchUpload

Error message

NoSuchUpload: upload ID is invalid or the upload has been aborted

What it means

ZombieJob.scaleInfo() is only meaningful for map attempts (its whole job is scaling node-local/rack-local/rack-remote runtimes), so after the Values.MAP branch it throws IllegalArgumentException('taskType can only be MAP: <t>') for anything else. scaleInfo() is reached from getMapTaskAttemptInfoAdjusted() when a logged successful map attempt is re-simulated at a different locality; the error therefore implies the logged task carrying that attempt is not typed MAP even though it was fetched through the map path — a task-type mismatch inside the trace or in the code that fetched the task.

Source

Thrown at hadoop-cloud-storage-project/hadoop-bos/src/main/java/org/apache/hadoop/fs/bos/BosClientProxyImpl.java:425

  /** {@inheritDoc} */
  @Override
  public CompleteMultipartUploadResponse
      completeMultipartUpload(
          CompleteMultipartUploadRequest request)
      throws IOException {
    CompleteMultipartUploadResponse response = null;
    try {
      response =
          bosClient.completeMultipartUpload(request);
    } catch (BceServiceException e) {
      if (BOS_NO_SUCH_KEY_CODE == e.getStatusCode()
          && e.getErrorCode() != null
          && e.getErrorCode().trim()
              .equals("NoSuchUpload")) {
        LOG.warn("The upload ID might be invalid, or"
            + " the multipart upload might have been"
            + " aborted or completed.");
        throw new IOException(
            "NoSuchUpload: upload ID is invalid or"
                + " the upload has been aborted", e);
      } else {
        handleBosServiceException(e);
      }

    }
    return response;
  }

  /** {@inheritDoc} */
  @Override
  public InitiateMultipartUploadResponse
      initiateMultipartUpload(
          InitiateMultipartUploadRequest request)
      throws IOException {
    InitiateMultipartUploadResponse response = null;
    try {

View on GitHub (pinned to 2add963021)

Solutions

  1. Verify the trace's internal consistency: each task in the MAP list must have taskType MAP and its attempts must belong to it (compare taskIDs/attemptIDs).
  2. Regenerate the trace with rumen tooling from the original job history rather than editing it by hand.
  3. In custom lookups, filter by getTaskType() == Values.MAP before indexing into the map task list, and skip mismatched records with a warning.

Example fix

// before: fetching by number from a mixed list
LoggedTask t = allTasks.get(taskNumber);
// t.getTaskType() may be REDUCE -> scaleInfo() throws later

// after: filter by type first
LoggedTask t = null;
for (LoggedTask c : allTasks) {
  if (c.getTaskType() == Values.MAP && mapIndex++ == taskNumber) { t = c; break; }
}
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isMapTaskWithMapAttempts(LoggedTask t, LoggedTaskAttempt a) {
  return t.getTaskType() == Values.MAP && a != null
      && (a.getAttemptID() == null || t.getTaskID() == null
          || a.getAttemptID().toString().startsWith(t.getTaskID().toString()));
}

Type guard

static boolean isMapTask(LoggedTask t) {
  return t != null && t.getTaskType() == Values.MAP;
}

Prevention

When it happens

Trigger: getLoggedTask(TaskType.MAP, n) returning a LoggedTask whose internal getTaskType() is REDUCE/CLEANUP/SETUP (trace lists the attempt under a map index but the record says otherwise), then locality-adjusted replay forcing the scaleInfo() branch; hand-assembled LoggedTask/LoggedTaskAttempt pairs with inconsistent types.

Common situations: Traces whose task lists were reordered or edited so attempt-to-task association is off by one; custom JobStory code that looks up tasks by number across mixed-type lists; older traces mixing SETUP/CLEANUP tasks into the map list.

Related errors


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