apache/druid · error · IOE
Failed to stream logs from: %s
Error message
Failed to stream logs from: %s
What it means
This IOException is thrown when streamTaskFile receives a BlobStorageException while trying to stream a task file from Azure blob storage. The message includes the blob taskKey, indicating the Azure service itself returned an error (404 not found, 403 auth failure, 412 precondition, etc.) for the requested blob.
Source
Thrown at extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureTaskLogs.java:165
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)
{
return StringUtils.format("%s/%s/status.json", config.getPrefix(), taskid);
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Confirm the blob exists: az storage blob list --container-name <container> --prefix <taskKey> and compare with the configured druid.storage.prefix
- If 404, verify the task actually completed successfully and its logs were pushed before being requested
- If 403, validate the account key / SAS token and that it grants read (and list) permissions on the container
- Retry on transient 5xx status codes; Azure storage occasionally returns transient service errors
Example fix
// before (caller assumes blob exists)
Optional<InputStream> s = taskLogs.streamTaskLog(taskId, 0);
// after
Optional<InputStream> s = taskLogs.streamTaskLog(taskId, 0);
if (!s.isPresent()) {
log.warn("Task log for %s not found in Azure storage", taskId);
} Defensive patterns
Strategy: try-catch
Try / catch
try { Optional<InputStream> s = taskLogs.streamTaskLog(taskId, offset); if (!s.isPresent()) { /* blob absent: handle gracefully */ } } catch (IOException e) { log.error("Failed to stream task file: {}", e.getMessage()); } Prevention
- Match druid.storage.prefix exactly with what the writer used; prefix mismatches are the top cause of 404s
- Only stream task files after the task has completed successfully
- Check blob existence (pathExists / az storage blob exists) before streaming in tooling code
- Verify read permissions on the SAS token/key used by the coordinator/overlord
When it happens
Trigger: streamTaskLog/streamTaskPayload/streamTaskReports/streamTaskStatus requests a blob whose read triggers a BlobStorageException from Azure — typically a 404 because the task log/report/status/payload was not written to container+taskKey, or 403 due to bad credentials/SAS permissions.
Common situations: Requesting logs for a task that never ran or whose logs were killed by killOlderThan; wrong druid.storage.prefix so the constructed taskKey does not match the uploaded blob; container or SAS token lacking read permission; region-outage 5xx errors.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- IOException wrapping underlying cause
- IOException wrapping underlying cause
- Recoverable exception
- Failed to get blob item from Azure container[%s], prefix[%s
- RuntimeException wrapping underlying cause
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/9fc39494b67a15df.
Report an issue: GitHub.