JuliusBrussee/caveman · error
objectstore: delete
Error message
objectstore: delete %q: %w
What it means
minioStore.Delete wraps a failure from client.RemoveObject. It means the object store rejected or failed the removal request — not that the key was absent (RemoveObject is idempotent and typically succeeds for missing keys). The key is embedded in the message and the underlying error is preserved with %w.
Solutions
- Check the wrapped error via minio.ToErrorResponse for AccessDenied and fix bucket/IAM policy to allow s3:DeleteObject.
- Retry on transient 5xx/network errors with backoff.
- Verify the bucket name and endpoint in the store configuration.
- Confirm credentials are valid and not expired (mc admin or console).
- Check bucket versioning/retention (object lock) rules that may block removal.
Example fix
// before
err := store.Delete(ctx, key)
// after
if err := store.Delete(ctx, key); err != nil {
var minioErr minio.ErrorResponse
if errors.As(err, &minioErr) && minioErr.Code == "AccessDenied" {
return fmt.Errorf("delete %s: missing s3:DeleteObject permission: %w", key, err)
}
return err
} Defensive patterns
Strategy: try-catch
Try / catch
if err := store.Delete(ctx, key); err != nil {
var mr minio.ErrorResponse
if errors.As(err, &mr) && mr.Code == "AccessDenied" {
// surface as config/permission problem, do not retry
}
return err
} Prevention
- Provision IAM with s3:DeleteObject before deploying delete paths.
- Smoke-test delete permissions against the real bucket in CI.
- Treat deletes as idempotent; don't pre-check existence.
- Alert on AccessDenied codes — they indicate policy drift, not transient faults.
When it happens
Trigger: Calling Delete(ctx, key) (directly or via deleteVersions from DeleteAllVersions) when RemoveObject returns a non-nil error: permission denied on the bucket, network failure, wrong bucket name, read-only bucket policy, or storage backend outage.
Common situations: IAM/bucket policy lacking s3:DeleteObject; pointing at a versioned bucket where policies block deletes; transient MinIO/S3 5xx; misconfigured bucket after environment change; Docker-compose MinIO restarted with different credentials.
Related errors
- objectstore: delete version
- objectstore: stat
- objectstore: list page
- objectstore: list
- objectstore: list versions
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/4f117ee95a517c96.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/objectstore/objectstore.go:308
if maxBytes <= 0 {
maxBytes = 64 << 20
}
body, err := io.ReadAll(io.LimitReader(obj, maxBytes+1))
if err != nil {
if minio.ToErrorResponse(err).Code == "NoSuchKey" {
return nil, ErrNotFound
}
return nil, fmt.Errorf("objectstore: read %q: %w", key, err)
}
if int64(len(body)) > maxBytes {
return nil, ErrTooLarge
}
return body, nil
}
func (m *minioStore) Delete(ctx context.Context, key string) error {
if err := m.client.RemoveObject(ctx, m.bucket, key, minio.RemoveObjectOptions{}); err != nil {
return fmt.Errorf("objectstore: delete %q: %w", key, err)
}
return nil
}
func (m *minioStore) DeleteAllVersions(ctx context.Context, key string) error {
return m.deleteVersions(ctx, key, true)
}
func (m *minioStore) DeletePrefixAllVersions(ctx context.Context, prefix string) error {
return m.deleteVersions(ctx, prefix, false)
}
func (m *minioStore) deleteVersions(ctx context.Context, keyOrPrefix string, exact bool) error {
found := false
for obj := range m.client.ListObjects(ctx, m.bucket, minio.ListObjectsOptions{
Prefix: keyOrPrefix, Recursive: true, WithVersions: true,
}) {
if obj.Err != nil {View on GitHub (pinned to 3ee70a1026)