ARTICLE AD BOX
I am using java batch SDK for manage blob.
Versioning and soft delete is enabled for this container
Using below code to delete all version of file
import java.util.ArrayList; import java.util.List; import java.util.Locale; import com.azure.core.http.HttpClient; import com.azure.core.http.okhttp.OkHttpAsyncHttpClientBuilder; import com.azure.core.http.rest.Response; import com.azure.storage.blob.BlobClient; import com.azure.storage.blob.BlobContainerClient; import com.azure.storage.blob.BlobContainerClientBuilder; import com.azure.storage.blob.batch.BlobBatch; import com.azure.storage.blob.batch.BlobBatchClient; import com.azure.storage.blob.batch.BlobBatchClientBuilder; import com.azure.storage.blob.models.BlobListDetails; import com.azure.storage.blob.models.ListBlobsOptions; import com.azure.storage.common.StorageSharedKeyCredential; public class BlobVersionBatchDeleteWithBatchAPI2 { private static final String CONTAINER = "#####"; private static final String ACCOUNT = "######"; private static final HttpClient HTTP_CLIENT = new OkHttpAsyncHttpClientBuilder().build(); public static void main(String[] args) { if (args.length < 1) { System.err.println("Usage: BlobVersionBatchDelete <accessKey>"); return; } String blobName = "2147850/version_10_soft_del_1/20"; BlobContainerClient containerClient = getBlobContainerClient(args[0]); BlobBatchClient batchClient = new BlobBatchClientBuilder(containerClient).buildClient(); List<String> versionUrls = new ArrayList<>(); List<String> currentversionUrls = new ArrayList<>(); // Step 1: Collect version URLs containerClient .listBlobs(new ListBlobsOptions().setPrefix(blobName).setDetails( new BlobListDetails().setRetrieveVersions(true).setRetrieveDeletedBlobs(true)), null) .forEach(blobItem -> { boolean skip = false; if (!blobName.equals(blobItem.getName())) { skip = true; } if (blobItem.getVersionId() == null) { skip = true; } // skip current version if (Boolean.TRUE.equals(blobItem.isCurrentVersion())) { System.out.printf("[SKIP] Current version: %s%n", blobItem.getVersionId()); skip = true; } // Skip soft-deleted if (Boolean.TRUE.equals(blobItem.isDeleted())) { System.out.printf("[SKIP] Deleted entry: %s%n", blobItem.getVersionId()); skip = true; } System.out.printf("[LIST] Version: [%s] | isCurrentVersion: %s,%b%n", blobItem.getVersionId(), blobItem.isCurrentVersion(), skip); String versionUrl = containerClient.getBlobClient(blobName) .getVersionClient(blobItem.getVersionId()).getBlobUrl(); if (!skip) { versionUrls.add(versionUrl); } else if (Boolean.TRUE.equals(blobItem.isCurrentVersion())) { currentversionUrls.add(versionUrl); } }); BlobBatch batchOp = batchClient.getBlobBatch(); Response<Void> deleteResponse1 = null; for (String url : versionUrls) { System.out.println("Adding to batch delete: " + url); deleteResponse1 = batchOp.deleteBlob(url); } batchClient.submitBatch(batchOp); System.out.printf("Delete operation 1 completed with status code: %d%n", deleteResponse1.getStatusCode()); // Step 3: Delete base blob // containerClient.getBlobClient(blobName).deleteIfExists(); BlobClient blobClient = containerClient.getBlobClient(blobName); blobClient.delete(); batchOp = batchClient.getBlobBatch(); for (String url : currentversionUrls) { System.out.println("Adding to batch delete: " + url); batchOp.deleteBlob(url); } batchClient.submitBatch(batchOp); System.out.println("All versions deleted using batch."); } private static BlobContainerClient getBlobContainerClient(String accessKey) { String endPoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net/%s", ACCOUNT, CONTAINER); StorageSharedKeyCredential storageCreds = new StorageSharedKeyCredential(ACCOUNT, accessKey); return new BlobContainerClientBuilder().endpoint(endPoint).httpClient(HTTP_CLIENT).credential(storageCreds) .buildClient(); } }But Getting error while delete base blob
BlobClient blobClient = containerClient.getBlobClient(blobName); <br/> blobClient.delete();
Output and ERROR
[LIST] Version: [2026-03-26T13:27:28.5647481Z] | isCurrentVersion: null,false [SKIP] Current version: 2026-03-26T13:27:39.8043318Z [LIST] Version: [2026-03-26T13:27:39.8043318Z] | isCurrentVersion: true,true Adding to batch delete: https://account.blob.core.windows.net/test-container/2147850%2Fversion_10_soft_del_1%2F20?versionid=2026-03-26T13:27:28.5647481Z Delete operation 1 completed with status code: 202 Exception in thread "main" com.azure.storage.blob.models.BlobStorageException: Status code 404, "<?xml version="1.0" encoding="utf-8"?><Error><Code>BlobNotFound</Code><Message>The specified blob does not exist. RequestId:<REQ_ID> Time:2026-03-27T06:55:50.4122729Z</Message></Error>" at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:733) at com.azure.core.implementation.MethodHandleReflectiveInvoker.invokeWithArguments(MethodHandleReflectiveInvoker.java:35) at com.azure.core.implementation.http.rest.ResponseExceptionConstructorCache.invoke(ResponseExceptionConstructorCache.java:51) at com.azure.core.implementation.http.rest.RestProxyBase.instantiateUnexpectedException(RestProxyBase.java:356) at com.azure.core.implementation.http.rest.AsyncRestProxy.lambda$ensureExpectedStatus$1(AsyncRestProxy.java:128) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:113) at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171) at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194) at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2068) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) at reactor.core.publisher.FluxHide$SuppressFuseableSubscriber.onNext(FluxHide.java:137) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) at reactor.core.publisher.FluxHide$SuppressFuseableSubscriber.onNext(FluxHide.java:137) at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:151) at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:172) at com.azure.core.http.okhttp.OkHttpAsyncHttpClient$OkHttpCallback.onResponse(OkHttpAsyncHttpClient.java:270) at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642) at java.base/java.lang.Thread.run(Thread.java:1583) Suppressed: java.lang.Exception: #block terminated with an error at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99) at reactor.core.publisher.Mono.block(Mono.java:1707) at com.azure.storage.common.implementation.StorageImplUtils.blockWithOptionalTimeout(StorageImplUtils.java:147) at com.azure.storage.blob.specialized.BlobClientBase.deleteWithResponse(BlobClientBase.java:1265) at com.azure.storage.blob.specialized.BlobClientBase.delete(BlobClientBase.java:1230) at BlobVersionBatchDeleteWithBatchAPI2.main(BlobVersionBatchDeleteWithBatchAPI2.java:97)