Conditional Requests
Conditional requests are used to determine if an action is to be performed based on a metadata comparison:
if-match
type of parameters (and its counterpartif-none-match
) can be used to check an object against anETag
- both
if-match
andif-none-match
parameters can take the wildcard value*
- both
if-modified-since
type of parameters (and its counterpart,if-unmodified-since
) can be used to check an object against a creation dateif-match-size
andif-match-last-modified-time
are used forDeleteObject
operations
Conditional requests can also be applied via bucket policies to eg: prevent data overwrite. For an example, please refer to the Bucket policy How-To guide.
Some applications for conditional requests are: handling concurrent requests gracefully, bandwidth savings or to implement exquisite architectural patterns on top of SOS.
Requirements
These parameters are generally available, and need only support from the client (eg: AWS S3 cli, Java SDK, etc). In case of multiple conditional parameters for a single request, SOS follows RFC7232 as closely as possible.
Operations
All examples are assuming you are using the AWS S3 cli, however most S3 clients should have support for conditional requests. Date parameters are formatted as defined by RFC3339 or RFC822:
2025-06-09T15:40:42+00:00
Tue, 05 Aug 2025 11:32:21 +0000
get-object
Conditional get requests can be useful when the client may expect an existing object to be in place, and may want to save bandwidth if the client has a local copy.
When retrieving an object, the following parameters can be specified:
--if-match <ETag>
gets the object if theETag
matches the objectETag
--if-none-match <ETag>
gets the object if theETag
does not match the objectETag
--if-modified-since <Timestamp>
gets the object if the objectLastModified
is equal or after theTimestamp
--if-unmodified-since <Timestamp>
gets the object if the objectLastModified
is before theTimestamp
put-object
Conditional put requests can be useful in a high concurrency scenario, where multiple clients can try to upload a given object but only one should succeed.
When uploading an object, the following parameters can be specified:
--if-match <ETag>
puts the object if theETag
matches the objectETag
--if-none-match <ETag>
puts the object if theETag
does not match the objectETag
copy-object
Copying an object can accept the following conditional parameters:
--copy-source-if-match <ETag>
copy if the source objectETag
matches theETag
--copy-source-if-none-match <ETag>
copy if the source objectETag
does not match theETag
--copy-source-if-modified-since <Timestamp>
copy if the source objectLastModified
is equal or after theTimestamp
--copy-source-if-unmodified-since <Timestamp>
copy if the source objectLastModified
is before theTimestamp
All the parameters refer to the source object attributes, and are similar to get-object
parameters.
delete-object
Conditional deletes can supply the following parameters:
--if-match <ETag>
object will be deleted if itsETag
matches the suppliedETag
--if-match-last-modified-time <Timestamp>
object will be deleted if itsLastModified
matches the suppliedTimestamp
--if-match-size <Size>
object will be deleted if itsSize
matches the suppliedSize
Example
Below is an example of using the aws cli to conditionally put or get an object.
# first we put an object
$ aws s3api put-object --bucket my-bucket --key mykey --body /tmp/myobj.bin
{
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"VersionId": "1152004336876784859"
}
# we can ensure we overwrite an object given its ETag
# this can be useful for a client that wants to put only if the object hasn't been modified in the meantime
$ aws s3api put-object --bucket my-bucket --key mykey --body /tmp/myobj.bin --if-match "d41d8cd98f00b204e9800998ecf8427e"
{
"ETag": "\"323bf3388a58620e50b5b22f550236bb\"",
"VersionId": "1152004380476574947"
}
# we can also ensure we overwrite anything
$ aws s3api put-object --bucket my-bucket --key mykey --body /tmp/myobj.bin --if-match "*"
{
"ETag": "\"3cd3e5bf2f0f53862405768788fd17fb\"",
"VersionId": "1152004396721115840"
}
# a non-matching ETag will fail
$ aws s3api put-object --bucket my-bucket --key mykey --if-match "<some etag>"
An error occurred (PreconditionFailed) when calling the PutObject operation: Your preconditions were not met.
# but a common case is to only put an object if there isn't one
$ aws s3api put-object --bucket my-bucket --key mykey --body /tmp/myobj.bin --if-none-match "*"
An error occurred (PreconditionFailed) when calling the PutObject operation: Your preconditions were not met.
##
# assuming we have a copy of the object, a client may only be interested in getting different or newer versions
$ aws s3api get-object --bucket mybuckey --key mykey --if-none-match "<some old etag>" /tmp/mykey
{
"AcceptRanges": "bytes",
"LastModified": "2025-08-06T11:59:15+00:00",
"ContentLength": 0,
"ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
"VersionId": "1152004396721115840",
"ContentType": "application/binary",
"Metadata": {}
}
# we can also request an object only if a more recent modification exists
$ aws s3api get-object --bucket mybucket --key mykey --if-modified-since "2025-08-06T11:59:25+00:00" /dev/null
An error occurred (304) when calling the GetObject operation: Not Modified
##
# we can also ask to delete an object only if we match the ETag
# because another client may have updated the object in the meantime
$ aws s3api delete-object --bucket my-bucket --key mykey --if-match "<some old etag>"
An error occurred (PreconditionFailed) when calling the DeleteObject operation: Your preconditions were not met.
# but if the object is still the one the client knows (the etag will match), the object can be safely deleted
$ aws s3api delete-object --bucket my-bucket --key mykey --if-match "d41d8cd98f00b204e9800998ecf8427e"
{
"DeleteMarker": true,
"VersionId": "1152006421454263029"
}