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
- Inspect the wrapped cause of the IOException to see the actual SDK exception
- Retry the stream operation — transient network issues while opening blob streams are common
- Verify the blob exists and the requested start offset is within the blob size to avoid skip() failures
- 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
- Ensure requested offsets are within the blob length before streaming
- Configure adequate retries in the Azure SDK client used by the extension
- Treat IOExceptions with transient causes (timeouts, 5xx) as retryable, not fatal
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
- RuntimeException wrapping underlying cause
- Failed to stream logs from: %s
- IOException wrapping underlying cause
- Recoverable exception
- Failed to get blob item from Azure container[%s], prefix[%s
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/164b7bfae73ed389.
Report an issue: GitHub.