apache/hadoop · error · AbfsRestOperationException

FNS-Blob delete was not successful for path: {}

Error message

FNS-Blob delete was not successful for path: {}

What it means

On non-HNS accounts, deletion is orchestrated by BlobDeleteHandler (enumerate blobs, delete each). If handler.execute() returns false, AbfsBlobClient throws a client-synthesized AbfsRestOperationException with HTTP 500, AzureServiceErrorCode.UNKNOWN and message 'FNS-Blob delete was not successful for path: <path>'. As with rename, the 500 is generated by the driver; the actual per-blob failure (lease, permission, throttle) appears in the handler's logs.

Source

Thrown at hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsBlobClient.java:1391

   * @return executed rest operation containing response from server.
   * @throws AzureBlobFileSystemException if rest operation fails.
   */
  @Override
  public AbfsRestOperation deletePath(final String path,
      final boolean recursive,
      final String continuation,
      final TracingContext tracingContext) throws AzureBlobFileSystemException {
    BlobDeleteHandler blobDeleteHandler = getBlobDeleteHandler(path, recursive,
        tracingContext);
    if (blobDeleteHandler.execute()) {
      final AbfsUriQueryBuilder abfsUriQueryBuilder
          = createDefaultUriQueryBuilder();
      final URL url = createRequestUrl(path, abfsUriQueryBuilder.toString());
      final List<AbfsHttpHeader> requestHeaders = createDefaultHeaders();
      return getSuccessOp(AbfsRestOperationType.DeletePath,
          HTTP_METHOD_DELETE, url, requestHeaders);
    } else {
      throw new AbfsRestOperationException(HTTP_INTERNAL_ERROR,
          AzureServiceErrorCode.UNKNOWN.getErrorCode(),
          ERR_DELETE_BLOB + path,
          null);
    }
  }

  @VisibleForTesting
  public BlobDeleteHandler getBlobDeleteHandler(final String path,
      final boolean recursive,
      final TracingContext tracingContext) {
    return new BlobDeleteHandler(new Path(path), recursive, this,
        tracingContext);
  }

  /**
   * Set the owner of the file or directory.
   * Not supported for HNS-Disabled Accounts.
   * @param path on which owner has to be set.

View on GitHub (pinned to 2add963021)

Solutions

  1. Inspect the driver logs for the per-blob error the handler recorded and fix that root cause (break leases, widen the token scope)
  2. Retry the delete — partially deleted trees make forward progress on each attempt
  3. Quiesce concurrent writers on the subtree before recursive delete
  4. Back off if metrics show throttling during bulk deletion
Defensive patterns

Strategy: retry

Validate before calling

if (!fs.exists(p)) return true; // already gone
fs.delete(p, true);

Try / catch

try {
  fs.delete(p, true);
} catch (AbfsRestOperationException e) {
  // handler logged the per-blob cause (lease/permission/throttle);
  // fix that, then retry — recursive deletes make progress each round
}

Prevention

When it happens

Trigger: fs.delete(path, recursive) on a flat-namespace account when listing or any individual blob delete fails: an active blob lease, a SAS token without delete scope, transient 5xx/429 responses, or concurrent writers recreating blobs during a recursive delete.

Common situations: Deleting trees while writers still hold leases or write; least-privilege SAS credentials; mass deletions triggering throttling; cleanup racing job retries.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/edfee870a5912ca4. Report an issue: GitHub.