apache/druid · error · IllegalStateException

Unable to read the task id from the file: [%s]

Error message

Unable to read the task id from the file: [%s]

What it means

After confirming the success file exists, findSuccessfulPartitionOutput reads its contents as the producing task id. If IOUtils.toString returns null, this ISE is thrown because a null task id makes it impossible to locate the partition output. In practice this happens only if the underlying stream yields null content (unusual; usually an empty file yields an empty string instead).

Source

Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/shuffle/input/DurableStorageInputChannelFactory.java:187

    String successfulFilePath = getWorkerOutputSuccessFilePath(controllerTaskId, stageNumber, workerNo);

    if (!storageConnector.pathExists(successfulFilePath)) {
      throw new ISE(
          "No file present at the location [%s]. Unable to read the outputs of stage [%d], partition [%d] for the worker [%d]",
          successfulFilePath,
          stageNumber,
          partitionNumber,
          workerNo
      );
    }

    String successfulTaskId;

    try (InputStream is = storageConnector.read(successfulFilePath)) {
      successfulTaskId = IOUtils.toString(is, StandardCharsets.UTF_8);
    }
    if (successfulTaskId == null) {
      throw new ISE("Unable to read the task id from the file: [%s]", successfulFilePath);
    }
    LOG.debug(
        "Reading output of stage [%d], partition [%d] from task id [%s]",
        stageNumber,
        partitionNumber,
        successfulTaskId
    );

    return getPartitionOutputsFileNameWithPathForPartition(
        controllerTaskId,
        stageNumber,
        workerNo,
        partitionNumber,
        successfulTaskId
    );
  }

  /**

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Inspect the success file contents in deep storage; if empty/corrupt, rerun the query to regenerate it.
  2. Check your storage connector extension implementation to ensure it never returns null for existing objects.
  3. Check producer task logs for a crash between creating and writing the success file.

Example fix

// before: only null check
successfulTaskId = IOUtils.toString(is, StandardCharsets.UTF_8);
if (successfulTaskId == null) { throw new ISE(...); }

// after: also reject empty ids
successfulTaskId = IOUtils.toString(is, StandardCharsets.UTF_8);
if (successfulTaskId == null || successfulTaskId.trim().isEmpty()) {
  throw new ISE("Success file [%s] has empty task id", successfulFilePath);
}
Defensive patterns

Strategy: validation

Validate before calling

// before relying on the marker content
String taskId = readSuccessFile(path);
if (taskId == null || taskId.trim().isEmpty()) {
  throw new IllegalStateException("Corrupt success marker at " + path + " — rerun query");
}

Try / catch

try {
  resolveProducerTask();
} catch (IllegalStateException e) {
  if (e.getMessage().startsWith("Unable to read the task id")) { rerunQuery(); }
  else { throw e; }
}

Prevention

When it happens

Trigger: Reading the '_success' file via storageConnector.read and getting a null string back: truncated/corrupt success file, a storage connector implementation that returns null for empty objects, or a race where the file content is not yet visible.

Common situations: Corrupt or empty success marker in deep storage caused by a producer crash during write; unusual custom storage connector implementations (extensions) that return null streams/data for empty files.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/915a7dcefe2fbce4. Report an issue: GitHub.