apache/beam · error · IOException
delete does not delete containers.
Error message
delete does not delete containers.
What it means
delete() refuses to delete anything whose resourceId has no blob component, i.e. an azfs container root. Containers cannot be removed through this filesystem API (it handles virtual folders and blobs only), so it throws an IOException with this message. This prevents users from accidentally wiping a whole container via the generic delete API.
Solutions
- Remove the container with the Azure SDK directly: blobContainerClient.delete() or 'az storage container delete'.
- Adjust the path list to only include actual blobs / virtual directories (skip container roots).
- Use a glob match (azfs://container/**) and delete only matched leaf blobs.
- Add a guard in your cleanup loop that skips resources where getBlob() == null.
Example fix
// before
FileSystems.delete(ImmutableList.of(FileSystems.matchNewResource("azfs://mycontainer", false))); // throws
// after
// delete contents via glob, or drop the container with the Azure SDK
MatchResult all = FileSystems.match("azfs://mycontainer/**");
FileSystems.delete(all.metadata().stream().map(MatchResult.Metadata::resourceId).collect(ImmutableList.toImmutableList())); Defensive patterns
Strategy: validation
Validate before calling
// skip container-root resources before delete
List<ResourceId> deletable = resourceIds.stream()
.filter(id -> !id.toString().matches("azfs://[^/]+/?"))
.collect(Collectors.toList());
FileSystems.delete(deletable); Try / catch
try {
FileSystems.delete(ids);
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().contains("does not delete containers")) {
// drop container via Azure SDK: containerClient.delete();
} else { throw e; }
} Prevention
- Never include the container root in recursive delete lists.
- Use glob matches (azfs://container/**) to collect only blobs.
- Use the Azure SDK's container client when you truly intend to drop a container.
When it happens
Trigger: Calling FileSystems.delete() with an AzfsResourceId whose getBlob() is null — typically a path like azfs://container or azfs://container/ that resolves to the container itself.
Common situations: Cleanup code that deletes directories recursively and reaches the container root; constructing resource IDs from parsed URIs that lack a blob path; users expecting container deletion like the Azure SDK's deleteContainer().
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- The requested file doesn't exist.
- The resource to delete does not exist.
- Basepath %r must be an Azure Blob Storage path.
- Invalid path
- List operation failed
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/426426195fe2f712.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/azure/src/main/java/org/apache/beam/sdk/io/azure/blobstore/AzureBlobStoreFileSystem.java:412
@Override
protected void rename(
List<AzfsResourceId> srcResourceIds,
List<AzfsResourceId> destResourceIds,
MoveOptions... moveOptions)
throws IOException {
if (moveOptions.length > 0) {
throw new UnsupportedOperationException("Support for move options is not yet implemented.");
}
copy(srcResourceIds, destResourceIds);
delete(srcResourceIds);
}
/** This method will delete a virtual folder or a blob, not a container. */
@Override
protected void delete(Collection<AzfsResourceId> resourceIds) throws IOException {
for (AzfsResourceId resourceId : resourceIds) {
if (resourceId.getBlob() == null) {
throw new IOException("delete does not delete containers.");
}
BlobContainerClient container =
client.get().getBlobContainerClient(resourceId.getContainer());
// deleting a blob that is not a directory
if (!resourceId.isDirectory()) {
BlobClient blob = container.getBlobClient(resourceId.getBlob());
if (!blob.exists()) {
throw new FileNotFoundException("The resource to delete does not exist.");
}
blob.delete();
}
// deleting a directory (not a container)
else {
PagedIterable<BlobItem> blobsInDirectory =
container.listBlobsByHierarchy(resourceId.getBlob());View on GitHub (pinned to 12126d8942)