{"record":{"id":"190bbe3a3cae986e","repo":"apache/druid","slug":"runtimeexception-wrapping-underlying-cause-190bbe","errorCode":null,"errorMessage":"RuntimeException wrapping underlying cause","messagePattern":"RuntimeException wrapping underlying cause","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureTaskLogs.java","lineNumber":99,"sourceCode":"    log.info(\"Pushing task reports %s to: %s\", reportFile, taskKey);\n    pushTaskFile(reportFile, taskKey);\n  }\n\n  @Override\n  public void pushTaskStatus(String taskid, File statusFile)\n  {\n    final String taskKey = getTaskStatusKey(taskid);\n    log.info(\"Pushing task status %s to: %s\", statusFile, taskKey);\n    pushTaskFile(statusFile, taskKey);\n  }\n\n  private void pushTaskFile(final File logFile, String taskKey)\n  {\n    try {\n      azureStorage.uploadBlockBlob(logFile, config.getContainer(), taskKey, accountConfig.getMaxTries());\n    }\n    catch (Exception e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  @Override\n  public void pushTaskPayload(String taskid, File taskPayloadFile)\n  {\n    final String taskKey = getTaskPayloadKey(taskid);\n    log.info(\"Pushing task payload [%s] to location [%s]\", taskPayloadFile, taskKey);\n    pushTaskFile(taskPayloadFile, taskKey);\n  }\n\n  @Override\n  public Optional<InputStream> streamTaskPayload(String taskid) throws IOException\n  {\n    return streamTaskFile(0, getTaskPayloadKey(taskid));\n  }\n\n  @Override","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureTaskLogs.java#L81-L117","documentation":"pushTaskFile wraps any exception from azureStorage.uploadBlockBlob in a plain RuntimeException. This happens when a task log, report, status, or payload file cannot be uploaded to the configured Azure blob container. The RuntimeException is an opaque wrapper; the real failure (auth, network, container missing, throttling) is in the cause chain.","triggerScenarios":"Calling pushTaskLog, pushTaskReports, pushTaskStatus, or pushTaskPayload when azureStorage.uploadBlockBlob fails after maxTries — e.g., invalid container name, wrong account key/SAS token, transient storage outage, or blob name conflicts.","commonSituations":"Misconfigured druid.storage.container; expired or revoked storage keys; Azure throttling (429) exceeding maxTries during heavy task completion; network partition between Druid middle managers and Azure Storage.","solutions":["Read the getCause() chain of the RuntimeException to identify the underlying Azure SDK exception (BlobStorageException status code, IOException, etc.)","Verify druid.storage.container exists in the storage account and the account name/key/SAS token are valid (az storage container list)","Increase azure.maxTries if Azure throttling is suspected, and check Azure Storage metrics for 4xx/5xx responses","Check connectivity from Druid task JVMs to the Azure blob endpoint (proxy, DNS, firewall rules)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// preflight: verify container access before pushing\nazureStorage.getBlockBlobExists(config.getContainer(), taskKey, accountConfig.getMaxTries());","typeGuard":null,"tryCatchPattern":"try { taskLogs.pushTaskLog(taskId, logFile); } catch (RuntimeException e) { Throwable cause = e.getCause(); log.error(\"Azure upload failed: {}\", cause == null ? e : cause); }","preventionTips":["Validate container name and credentials with a startup preflight call (list blobs or get properties)","Set azure.maxTries high enough to absorb transient Azure throttling","Monitor getCause() for BlobStorageException status codes and alert on 403/404"],"tags":["azure","blob-storage","upload","wrapper-exception"],"backgroundTag":"file-write-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}