apache/druid · error · IOException

IOException wrapping underlying cause

Error message

IOException wrapping underlying cause

What it means

streamTaskFile wraps any non-BlobStorageException failure to open a blob input stream into an IOException. It is thrown when streaming a task payload, log, report, or status file from Azure fails for reasons other than a recognized blob error — e.g., stream creation or skip() failures, network errors, or SDK client errors.

Source

Thrown at extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureTaskLogs.java:161

      try {
        final long start;
        final long length = azureStorage.getBlockBlobLength(container, taskKey);

        if (offset > 0 && offset < length) {
          start = offset;
        } else if (offset < 0 && (-1 * offset) < length) {
          start = length + offset;
        } else {
          start = 0;
        }

        InputStream stream = azureStorage.getBlockBlobInputStream(container, taskKey);
        stream.skip(start);

        return Optional.of(stream);
      }
      catch (Exception e) {
        throw new IOException(e);
      }
    }
    catch (BlobStorageException e) {
      throw new IOE(e, "Failed to stream logs from: %s", taskKey);
    }
  }

  private String getTaskLogKey(String taskid)
  {
    return StringUtils.format("%s/%s/log", config.getPrefix(), taskid);
  }

  private String getTaskReportsKey(String taskid)
  {
    return StringUtils.format("%s/%s/report.json", config.getPrefix(), taskid);
  }

  private String getTaskStatusKey(String taskid)

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Inspect the wrapped cause of the IOException to see the actual SDK exception
  2. Retry the stream operation — transient network issues while opening blob streams are common
  3. Verify the blob exists and the requested start offset is within the blob size to avoid skip() failures
  4. Check druid.storage.container and account configuration if failures are persistent
Defensive patterns

Strategy: retry

Try / catch

try { Optional<InputStream> s = taskLogs.streamTaskLog(taskId, offset); } catch (IOException e) { if (isTransient(e)) retryWithBackoff(); else throw e; }

Prevention

When it happens

Trigger: Calling streamTaskLog/streamTaskReports/streamTaskStatus/streamTaskPayload when azureStorage.getBlockBlobInputStream throws a generic Exception (network failure, SDK error, interrupted stream setup, or skip(start) failure), distinct from the BlobStorageException branch at line 165.

Common situations: Transient network failures while opening the blob stream; Azure SDK client configuration problems; requesting an invalid byte range via skip() on a short stream; intermittent storage service errors not surfaced as BlobStorageException.

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/164b7bfae73ed389. Report an issue: GitHub.