{"record":{"id":"b9bbd093b112fb58","repo":"apache/druid","slug":"couldn-t-kill-segment-s-s","errorCode":null,"errorMessage":"Couldn't kill segment[%s]: [%s]","messagePattern":"Couldn't kill segment\\[(.+?)\\]: \\[(.+?)\\]","errorType":"exception","errorClass":"SegmentLoadingException","httpStatus":null,"severity":"error","filePath":"extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureDataSegmentKiller.java","lineNumber":128,"sourceCode":"    }\n  }\n\n\n  @Override\n  public void kill(DataSegment segment) throws SegmentLoadingException\n  {\n    log.info(\"Killing segment [%s]\", segment);\n\n    Map<String, Object> loadSpec = segment.getLoadSpec();\n    final String containerName = MapUtils.getString(loadSpec, \"containerName\");\n    final String blobPath = MapUtils.getString(loadSpec, \"blobPath\");\n    final String dirPath = Paths.get(blobPath).getParent().toString();\n\n    try {\n      azureStorage.emptyCloudBlobDirectory(containerName, dirPath);\n    }\n    catch (BlobStorageException e) {\n      throw new SegmentLoadingException(e, \"Couldn't kill segment[%s]: [%s]\", segment.getId(), e.getMessage());\n    }\n  }\n\n  @Override\n  public void killAll() throws IOException\n  {\n    if (segmentConfig.getContainer() == null || segmentConfig.getPrefix() == null) {\n      throw new ISE(\n          \"Cannot delete all segment files since Azure Deep Storage since druid.azure.container and druid.azure.prefix are not both set.\");\n    }\n    log.info(\n        \"Deleting all segment files from Azure storage location [bucket: '%s' prefix: '%s']\",\n        segmentConfig.getContainer(),\n        segmentConfig.getPrefix()\n    );\n    try {\n      AzureUtils.deleteObjectsInPath(\n          azureStorage,","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureDataSegmentKiller.java#L110-L146","documentation":"Thrown when emptying the Azure blob directory that holds a segment fails with a BlobStorageException during kill(). The segment ID and Azure error message are included so the operator can diagnose the storage-side failure.","triggerScenarios":"azureStorage.emptyCloudBlobDirectory(containerName, dirPath) throws BlobStorageException: e.g. the directory's blobs are immutable/leased, credentials lack delete permission, or the container no longer exists.","commonSituations":"Killing a segment after its container was deleted; RBAC/SAS token without blob delete; soft-delete enabled in the storage account causing 409 conflicts.","solutions":["Read e.getMessage() in the exception to identify the Azure status code","Grant the account delete permission on the container/blob path","Verify the segment's container still exists and the path matches druid.azure.container/prefix","Disable or account for blob immutability policies/soft-delete if kills must hard-delete"],"exampleFix":"// before\ncatch (BlobStorageException e) {\n  throw new SegmentLoadingException(e, \"Couldn't kill segment[%s]: [%s]\", segment.getId(), e.getMessage());\n}\n// after\ncatch (BlobStorageException e) {\n  if (e.getStatusCode() == 404) { return; } // already gone\n  throw new SegmentLoadingException(e, \"Couldn't kill segment[%s]: [%s]\", segment.getId(), e.getMessage());\n}","handlingStrategy":"try-catch","validationCode":"if (!blobContainerExists(containerName)) throw new IllegalStateException(\"Container \" + containerName + \" does not exist\");","typeGuard":null,"tryCatchPattern":"try { killer.kill(segment); } catch (SegmentLoadingException e) { Throwable cause = e.getCause(); if (cause instanceof BlobStorageException bse && bse.getStatusCode() == 404) return; throw e; }","preventionTips":["Handle 404 as success (segment already gone)","Check storage account immutability/soft-delete policies before large kill campaigns","Use SAS tokens with delete scope","Log the Azure request id from BlobStorageException for support tickets"],"tags":["azure","segment-deletion","permissions"],"backgroundTag":"http-error-response","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"}