juicedata/juicefs · error

delete failed: %s

Error message

delete failed: %s

What it means

This error is produced by the objbench 'delete an object' self-test case in JuiceFS when the ObjectStorage.Delete call fails on an object that was just successfully put. objbench verifies that each object-storage backend honors the basic Put/Delete/Head contract, and this message wraps the underlying backend error. It indicates the backend rejected or failed the DELETE operation rather than a bug in objbench itself.

Source

Thrown at cmd/objbench.go:864

		}
		defer blob.Delete(ctx, key) //nolint:errcheck
		if h, err := blob.Head(ctx, key); err != nil {
			return fmt.Errorf("failed to head object %s", err)
		} else {
			if h.Key() != key {
				return fmt.Errorf("expected key 'test' but got %s", h.Key())
			}
		}
		return nil
	})

	runCase("delete an object", func(blob object.ObjectStorage) error {
		br := []byte("hello")
		if err := blob.Put(ctx, key, bytes.NewReader(br)); err != nil {
			return fmt.Errorf("put object failed: %s", err)
		}
		if err := blob.Delete(ctx, key); err != nil {
			return fmt.Errorf("delete failed: %s", err)
		}
		if _, err := blob.Head(ctx, key); err == nil {
			return fmt.Errorf("expect err is not nil")
		}

		if err := blob.Delete(ctx, key); err != nil {
			return fmt.Errorf("delete not existed: %v", err)
		}
		return nil
	})

	runCase("delete non-exist", func(blob object.ObjectStorage) error {
		if err := blob.Delete(ctx, key); err != nil {
			return fmt.Errorf("deleting a non-existent object returns an error %v", err)
		}
		return nil
	})

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Check the wrapped backend error message (the %s payload) for the root cause (403, NoSuchBucket, timeout, etc.).
  2. Verify the credentials/policy allow DeleteObject / delete operations on the target bucket.
  3. Ensure the bucket/container exists and the endpoint URL is correct in the storage URL passed to objbench.
  4. If object lock/retention or versioning blocks deletes, adjust the bucket policy or test against a non-locked bucket.
  5. Retry to rule out transient network errors; then rerun objbench.

Example fix

// before (backend rejects delete)
if err := blob.Delete(ctx, key); err != nil {
    return fmt.Errorf("delete failed: %s", err)
}
// after: grant delete permission, e.g. S3 IAM policy
// {"Effect":"Allow","Action":"s3:DeleteObject","Resource":"arn:aws:s3:::mybucket/*"}
Defensive patterns

Strategy: try-catch

Validate before calling

// check delete permission before running
_, err := blob.Head(ctx, key)
_ = err // backend reachable check
deleteAllowed := policyAllowsDelete(storageURL) // verify IAM/policy out-of-band

Try / catch

err := blob.Delete(ctx, key)
if err != nil {
    log.Printf("delete failed, check write/delete perms and bucket: %v", err)
    return err
}

Prevention

When it happens

Trigger: The test uploads bytes 'hello' under the test key, then calls blob.Delete(ctx, key) and the storage backend returns a non-nil error — e.g. the bucket/container is missing, credentials lack delete permission, the backend is read-only, or a network/API error occurred during the delete request.

Common situations: Running `juicefs objbench` against a bucket where the access key has write but not delete rights (e.g. an S3 policy denying s3:DeleteObject); a versioning/retention (object lock, WORM) configuration blocking deletes; a misconfigured endpoint hitting a read-only replica; transient network failures.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/e63f2fc66a7a51ef. Report an issue: GitHub.