apache/druid · error · UncheckedIOException

Unable to read file : %s

Error message

Unable to read file : %s

What it means

When reading back the written frame file, openChannel wraps any IOException from opening the remote input stream in an UncheckedIOException with message 'Unable to read file : %s'. The file path exists (checked earlier) but opening the read stream failed — typically a storage-client-level error.

Source

Thrown at multi-stage-query/src/main/java/org/apache/druid/msq/shuffle/output/DurableStorageTaskOutputChannelFactory.java:140

          try {
            if (!storageConnector.pathExists(fileName)) {
              throw new ISE("File does not exist : %s", fileName);
            }
          }
          catch (Exception exception) {
            throw new RuntimeException(exception);
          }
          try {
            return ReadableInputStreamFrameChannel.open(
                storageConnector.read(fileName),
                fileName,
                remoteInputStreamPool,
                false,
                wireTransferableContext
            );
          }
          catch (IOException e) {
            throw new UncheckedIOException(StringUtils.format("Unable to read file : %s", fileName), e);
          }
        },
        partitionNumber
    );
  }

  @Override
  public PartitionedOutputChannel openPartitionedChannel(String name, boolean deleteAfterRead) throws IOException
  {
    final String fileName = DurableStorageUtils.getOutputsFileNameForPath(
        controllerTaskId,
        stageNumber,
        workerNumber,
        taskId,
        name
    );
    final CountingOutputStream countingOutputStream = new CountingOutputStream(storageConnector.write(fileName));
    final WritableFrameFileChannel writableChannel =

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Look at the wrapped IOException cause for the storage-specific error code (access denied, throttled, not found).
  2. Verify credentials and IAM permissions for reading the durable-storage location.
  3. Add/increase retry and backoff settings on the storage connector client.
  4. Ensure deep-storage cleanup jobs are not deleting the query's intermediate prefix while the query runs.

Example fix

null
Defensive patterns

Strategy: retry

Validate before calling

// preflight read check on the storage location
storageConnector.read(knownProbeKey).close(); // throws IOException early if credentials/permissions are broken

Try / catch

try {
  readOutput();
} catch (UncheckedIOException e) {
  if (isRetryable(e.getCause())) { retryWithBackoff(); } else { throw e; }
}

Prevention

When it happens

Trigger: The read lambda in openChannel calls storageConnector.read / remoteInputStreamPool to open the partition output file and receives an IOException: transient deep-storage outage, permission/credential errors, file deleted between existence check and read, throttling by the object store.

Common situations: Expired cloud credentials (S3/GCS/Azure) mid-query; object-store throttling (429) during large shuffles; security/plugin misconfiguration denying read access; concurrent cleanup deleting the file.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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