diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md
index 1d5eb946..0c05e8b2 100644
--- a/IMPLEMENTATION_COVERAGE.md
+++ b/IMPLEMENTATION_COVERAGE.md
@@ -7093,7 +7093,7 @@
- [X] delete_bucket_tagging
- [ ] delete_bucket_website
- [X] delete_object
-- [ ] delete_object_tagging
+- [x] delete_object_tagging
- [ ] delete_objects
- [ ] delete_public_access_block
- [ ] get_bucket_accelerate_configuration
diff --git a/moto/s3/models.py b/moto/s3/models.py
index 350a4fd1..b809c0fc 100644
--- a/moto/s3/models.py
+++ b/moto/s3/models.py
@@ -1566,6 +1566,10 @@ class S3Backend(BaseBackend):
bucket = self.get_bucket(bucket_name)
bucket.keys[key_name] = FakeDeleteMarker(key=bucket.keys[key_name])
+ def delete_object_tagging(self, bucket_name, key_name, version_id=None):
+ key = self.get_object(bucket_name, key_name, version_id=version_id)
+ self.tagger.delete_all_tags_for_resource(key.arn)
+
def delete_object(self, bucket_name, key_name, version_id=None):
key_name = clean_key_name(key_name)
bucket = self.get_bucket(bucket_name)
diff --git a/moto/s3/responses.py b/moto/s3/responses.py
index d4d872a8..10e68d56 100644
--- a/moto/s3/responses.py
+++ b/moto/s3/responses.py
@@ -1618,6 +1618,12 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
self.backend.cancel_multipart(bucket_name, upload_id)
return 204, {}, ""
version_id = query.get("versionId", [None])[0]
+ if "tagging" in query:
+ self.backend.delete_object_tagging(
+ bucket_name, key_name, version_id=version_id
+ )
+ template = self.response_template(S3_DELETE_KEY_TAGGING_RESPONSE)
+ return 204, {}, template.render(version_id=version_id)
self.backend.delete_object(bucket_name, key_name, version_id=version_id)
return 204, {}, ""
@@ -1935,6 +1941,12 @@ S3_DELETE_KEYS_RESPONSE = """
{% endfor %}
"""
+S3_DELETE_KEY_TAGGING_RESPONSE = """
+
+{{version_id}}
+
+"""
+
S3_OBJECT_ACL_RESPONSE = """
diff --git a/tests/test_s3/test_s3.py b/tests/test_s3/test_s3.py
index dbdd1b90..8ac227f4 100644
--- a/tests/test_s3/test_s3.py
+++ b/tests/test_s3/test_s3.py
@@ -2424,9 +2424,13 @@ def test_boto3_put_object_with_tagging():
s3.put_object(Bucket=bucket_name, Key=key, Body="test", Tagging="foo=bar")
- resp = s3.get_object_tagging(Bucket=bucket_name, Key=key)
+ s3.get_object_tagging(Bucket=bucket_name, Key=key)["TagSet"].should.contain(
+ {"Key": "foo", "Value": "bar"}
+ )
- resp["TagSet"].should.contain({"Key": "foo", "Value": "bar"})
+ s3.delete_object_tagging(Bucket=bucket_name, Key=key)
+
+ s3.get_object_tagging(Bucket=bucket_name, Key=key)["TagSet"].should.equal([])
@mock_s3