Skip to content

feature request: DeleteObject IfMatch for Directory Buckets #12783

@da1rren

Description

@da1rren

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

Despite providing an eTag that doesn't match the object the delete object request still succeeds.

Expected Behavior

The expected response would be for the localstack s3 api to throw a 412 Precondition Failed.

How are you starting LocalStack?

With a docker-compose file

Steps To Reproduce

How are you starting localstack (e.g., bin/localstack command, arguments, or docker-compose.yml)

docker compose up

services:
  localstack:
    container_name: localstack
    image: localstack/localstack:latest
    ports:
      - "127.0.0.1:4566:4566" # LocalStack Gateway
      - "127.0.0.1:4510:4510" # LocalStack Health endpoint (optional)
    environment:
      - SERVICES=s3,kms
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - ./src/scripts/:/etc/localstack/init/ready.d
      - /var/run/docker.sock:/var/run/docker.sock # Mount Docker socket for LocalStack
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:4510/_localstack/health" ]
      interval: 30s
      timeout: 10s
      retries: 5

Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

#!/bin/bash
awslocal s3 mb s3://securemint --region eu-west-1
KEY_ID=`awslocal kms create-key  --region eu-west-1 --query "KeyMetadata.KeyId" --output text`
awslocal kms create-alias --region eu-west-1 --alias-name alias/securemint --target-key-id $KEY_ID

Golang Example

I'm using the following aws packages:

	github.com/aws/aws-sdk-go-v2 v1.36.5
	github.com/aws/aws-sdk-go-v2/config v1.29.17
	github.com/aws/aws-sdk-go-v2/service/kms v1.41.1
	github.com/aws/aws-sdk-go-v2/service/s3 v1.81.0

I've written the following test case:

func TestIfMatchPrecondition(t *testing.T) {
	cfg, err := config.LoadDefaultConfig(context.TODO())
	assert.Nil(t, err)

	s3Client := s3.NewFromConfig(cfg, func(o *s3.Options) {
		o.UsePathStyle = true
	})

	putResp, err := s3Client.PutObject(context.TODO(), &s3.PutObjectInput{
		Bucket: aws.String(appCfg.KeyBucket),
		Key:    aws.String("test/object"),
		Body:   strings.NewReader("test123"),
	})
	assert.Nil(t, err)

	fmt.Println("object etag: " + *putResp.ETag)

	_, err = s3Client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
		Bucket:  aws.String(appCfg.KeyBucket),
		Key:     aws.String("test/object"),
		IfMatch: aws.String("XXX"), # A bad etag value which should cause the request to fail
	})
	assert.Error(t, err) # Test case fails as no error is thrown
}

Environment

- OS:
- LocalStack:
  LocalStack version: 4.5.1.dev46
  LocalStack Docker image sha: sha256:ac8efcc3f0291e07682f505d3d71022d3188a377d2a4a3320159e110ae8c420d
  LocalStack build date: 2025-06-20
  LocalStack build git hash: 6348947e8

Anything else?

No response

Metadata

Metadata

Assignees

Labels

aws:s3Amazon Simple Storage Servicestatus: backlogTriaged but not yet being worked ontype: featureNew feature, or improvement to an existing feature

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions