Question: How can I retrieve an Amazon S3 object that was deleted in a versioning-enabled bucket?

I want to retrieve an object that was deleted from my Amazon Simple Storage Service (Amazon S3) bucket that has versioning enabled. How can I do that?Short descriptionWhen you delete an object from a version-enabled bucket, Amazon S3 creates a delete marker for the object. The delete marker becomes the current version of the object, and the actual object becomes the previous version. With a delete marker, Amazon S3 responds to requests for the object as though the object was deleted. For example, if you send a GET request for the object, then Amazon S3 returns an error.You can retrieve an object that was deleted from a version-enabled bucket in one of these ways:Download the previous version of the object: To download the previous version of the object (the actual object), you must have permissions to s3:GetObjectVersion.Remove the delete marker: After you remove the delete marker, the actual object becomes the current version of the object. To remove the delete marker, you must have permissions to s3:DeleteObjectVersion. Also, you must remove the delete marker using the AWS account that owns or created the bucket.Note: If the bucket has MFA delete-enabled, you must use the designated multi-factor authentication (MFA) to remove the delete marker.

ResolutionDownload the previous version of the object using the Amazon S3 console1.    Open the Amazon S3 console.2.    From the list of buckets, open the bucket of the deleted object.3.    Navigate to the folder of the deleted object.4.    Turn on Show versions.5.    In the search bar, enter the name of the deleted object.6.    Select the previous version of the object (the actual object rather than the delete marker). Choose Actions, and then choose Download.Download the previous version of the object using the AWS Command Line Interface (AWS CLI)Note: If you receive errors when running AWS CLI commands, make sure that you’re using the most recent version of the AWS CLI.1.    Run the list-object-versions command on the bucket. Replace DOC-EXAMPLE-BUCKET with the name of your bucket.aws s3api list-object-versions --bucket DOC-EXAMPLE-BUCKET --prefix example.txtNote: This example includes the --prefix option to filter the results to the specified key name prefix. This option helps reduce the number of results, which saves time when your bucket contains a large number of object versions.2.    From the command output, copy the version ID of the previous version of the object (the actual object rather than the delete marker).3.    Run the get-object command for the version ID that you copied in the previous step. Replace DOC-EXAMPLE-BUCKET with the name of your bucket.aws s3api get-object --bucket DOC-EXAMPLE-BUCKET --key example.txt --version-id example.d6tjAKF1iObKbEnNQkIMPjj filename.txtRemove the delete marker using the Amazon S3 console1.    Open the Amazon S3 console from the AWS account that owns or created the bucket of the deleted object.2.    From the list of buckets, open the bucket of the deleted object.3.    Navigate to the folder of the deleted object.4.    Turn on Show versions.5.    In the search bar, enter the name of the deleted object.6.    Select the delete marker of the object.Warning: Review your selection carefully to be sure that it's the delete marker. If you delete an object version, it can't be retrieved.7.    Choose Delete.8.    In the Delete objects page, confirm that the correct delete marker is listed. Then, enter permanently delete to confirm deletion.9.    Choose Delete objects.Important: You can't use the Amazon S3 console to undelete folders. To do so, you must use the AWS CLI or the AWS SDK.Remove the delete marker using the AWS CLIRemove the delete mark on several objects1.    Run the list-object-versions command with the following --query parameter. Replace DOC-EXAMPLE-BUCKET with the name of your bucket.aws s3api list-object-versions --bucket DOC-EXAMPLE-BUCKET --prefix example.txt --query 'DeleteMarkers[?IsLatest==`true`]'Note: The following example command includes the --prefix option, which filters the results to the specified key name prefix. This option helps reduce the number of results, which saves time if your bucket contains a large volume of object versions.2.    The command returns all objects in the bucket that were deleted. From the command output, copy the version ID of the delete marker for the object that you want to retrieve.Warning: Review the version ID carefully to be sure that it's the version ID of the delete marker. If you delete an object version, it can't be retrieved.3.    Run the delete-object command for the version ID that you copied in the previous step. Replace DOC-EXAMPLE-BUCKET with the name of your bucket.aws s3api delete-object --bucket DOC-EXAMPLE-BUCKET --key example.txt --version-id 'example.d6tjAKF1iObKbEnNQkIMPjj'4.    After you remove the delete marker, the actual object is returned when you list the objects in the bucket. To verify that the delete marker was removed, run the ls command. Replace DOC-EXAMPLE-BUCKET with the name of your bucket.aws s3 ls s3://DOC-EXAMPLE-BUCKETRemove the delete marker on thousands of objects1.    Navigate to AWS CloudShell.2.    Run the following AWS CLI command. Replace DOC-EXAMPLE-BUCKET with the name of your bucket.aws s3api list-object-versions --bucket DOC-EXAMPLE-BUCKET --prefix examplefolder/ --output json --query 'DeleteMarkers[?IsLatest==`true`].[Key, VersionId]' | jq -r '.[] | "--key '\''" + .[0] + "'\'' --version-id " + .[1]' | xargs -L1 aws s3api delete-object --bucket DOC-EXAMPLE-BUCKETNote: This example uses the JQ tool from GitHub to parse the ListObjectVersions response for current version DeleteMarkers. You can make changes to this custom script example based on your specific use case. By default, JQ is installed on AWS CloudShell. If you don't interact with the shell environment, your shell session will end.Remove the delete marker on millions of objectsIf your bucket has millions of objects, then performing the LIST call can be expensive, resulting in a timeout. Therefore, consider using a custom script with the AWS SDK.