Specifying conditional headers for Blob service operations

Several Blob service operations support the use of conditional headers. You can specify conditional headers to carry out an operation only if a specified condition has been met.

The Blob service follows the HTTP/1.1 protocol specification for conditional headers.

Supported Conditional Headers

The supported conditional headers are described in the following table.

Conditional header Description
If-Modified-Since A DateTime value. Specify this header to perform the operation only if the resource has been modified since the specified time.
If-Unmodified-Since A DateTime value. Specify this header to perform the operation only if the resource has not been modified since the specified date/time.
If-Match An ETag value. Specify this header to perform the operation only if the resource's ETag matches the value specified. For versions 2011-08-18 and newer, the ETag can be specified in quotes.
If-None-Match An ETag value, or the wildcard character (*). Specify this header to perform the operation only if the resource's ETag does not match the value specified. For versions 2011-08-18 and newer, the ETag can be specified in quotes.

Specify the wildcard character (*) to perform the operation only if the resource does not exist, and fail the operation if it does exist.

Specifying Conditional Headers for Blob Service Read Operations in Version 2013-08-15 or Later

Beginning with version 2013-08-15, the Get Blob and Get Blob Properties operations support multiple conditional headers. You can specify any combination of supported conditional headers. The Blob service will evaluate these conditions according to following expression:

If-Match && If-Unmodified-Since && (If-None-Match || If-Modified-Since)

You can also provide multiple comma-separated values for If-Match and If-None-Match. If you specify multiple values for If-Match, then the Blob service performs a logical OR operation on all of the provided values before evaluating the entire expression. If you specify multiple values for if-None-Match, then the service performs a logical AND operation before evaluating the entire expression. Specifying multiple values for If-Modified-Since and If-Unmodified-Since is not supported and results in error code 400 (Bad Request).

This feature is enabled in order to comply with HTTP/1.1 specification and to cater to scenarios where a Content Delivery Network (CDN) or proxy server adds additional conditional headers to an inflight request. Below are some examples of different combinations of conditional headers.

Example 1:

Consider a Get Blob request containing the If-Match and If-Modified-Since headers. The following table indicates the result if the headers are evaluated individually, and the result if they are evaluated in combination.

Conditional headers Result if evaluated individually Result if evaluated in combination
If-Match 412 (Precondition Failed) 412 (Precondition Failed)
If-Modified-Since 200 (OK) 412 (Precondition Failed)
If-Match 412 (Precondition Failed) 412 (Precondition Failed)
If-Modified-Since 304 (Not Modified) 412 (Precondition Failed)
If-Match 200 (OK) 200 (OK)
If-Modified-Since 200 (OK) 200 (OK)
If-Match 200 (OK) 304 (Not Modified)
If-Modified-Since 304 (Not Modified) 304 (Not Modified)

Example 2:

Consider a request containing If-None-Match and If-Modified-Since headers.

Conditional headers Result if evaluated individually Result if evaluated in combination
If-None-Match 304 (Not Modified) 200 (OK)
If-Modified-Since 200 (OK) 200 (OK)
If-None-Match 200 (OK) 200 (OK)
If-Modified-Since 200 (OK) 200 (OK)
If-None-Match 200 (OK) 200 (OK)
If-Modified-Since 304 (Not Modified) 200 (OK)
If-None-Match 304 (Not Modified) 304 (Not Modified)
If-Modified-Since 304 (Not Modified) 304 (Not Modified)

Example 3:

Consider a request containing If-Modified-Since, If-Match and If-Unmodified-Since headers.

Conditional headers Result if evaluated individually Result if evaluated in combination
If-Modified-Since 200 (OK) 412 (Precondition Failed)
If-Match 412 (Precondition Failed) 412 (Precondition Failed)
If-Unmodified-Since 200 (OK) 412 (Precondition Failed)
If-Modified-Since 200 (OK) 412 (Precondition Failed)
If-Match 200 (OK) 412 (Precondition Failed)
If-Unmodified-Since 412 (Precondition Failed) 412 (Precondition Failed)
If-Modified-Since 304 (Not Modified) 412 (Precondition Failed)
If-Match 200 (OK) 412 (Precondition Failed)
If-Unmodified-Since 412 (Precondition Failed) 412 (Precondition Failed)
If-Modified-Since 304 (Not Modified) 304 (Not Modified)
If-Match 200 (OK) 304 (Not Modified)
If-Unmodified-Since 200 (OK) 304 (Not Modified)

Example 4:

Consider a request containing If-Modified-Since, If-None-Match, If-Unmodified-Since and If-Match headers.

Combination Individual http status code Get Blob status result
If-Modified-Since 200 (OK) 200 (OK)
If-None-Match 200 (OK) 200 (OK)
If-Unmodified-Since 200 (OK) 200 (OK)
If-Match 200 (OK) 200 (OK)
If-Modified-Since 200 (OK) 412 (Precondition Failed)
If-None-Match 304 (Not Modified) 412 (Precondition Failed)
If-Unmodified-Since 412 (Precondition Failed) 412 (Precondition Failed)
If-Match 200 (OK) 412 (Precondition Failed)
If-Modified-Since 200 (OK) 200 (OK)
If-None-Match 304 (Not Modified) 200 (OK)
If-Unmodified-Since 200 (OK) 200 (OK)
If-Match 200 (OK) 200 (OK)
If-Modified-Since 304 (Not Modified) 412 (Precondition Failed)
If-None-Match 200 (OK) 412 (Precondition Failed)
If-Unmodified-Since 200 (OK) 412 (Precondition Failed)
If-Match 412 (Precondition Failed) 412 (Precondition Failed)
If-Modified-Since 304 (Not Modified) 412 (Precondition Failed)
If-None-Match 200 (OK) 412 (Precondition Failed)
If-Unmodified-Since 412 (Precondition Failed) 412 (Precondition Failed)
If-Match 412 (Precondition Failed) 412 (Precondition Failed)
If-Modified-Since 304 (Not Modified) 200 (OK)
If-None-Match 200 (OK) 200 (OK)
If-Unmodified-Since 200 (OK) 200 (OK)
If-Match 200 (OK) 200 (OK)
If-Modified-Since 304 (Not Modified) 412 (Precondition Failed)
If-None-Match 304 (Not Modified) 412 (Precondition Failed)
If-Unmodified-Since 412 (Precondition Failed) 412 (Precondition Failed)
If-Match 200 (OK) 412 (Precondition Failed)

Specifying Conditional Headers for Read Operations in Versions Prior to 2013-08-15, and for Write Operations (All Versions)

When calling Blob service read operations (Get Blob and Get Blob Properties) with versions prior to 2013-08-15, and when calling any write operation regardless of version, keep in mind the following:

  • If a request specifies both the If-None-Match and If-Modified-Since headers, the request is evaluated based on the criteria specified in If-None-Match.

  • If a request specifies both the If-Match and If-Unmodified-Since headers, the request is evaluated based on the criteria specified in If-Match.

  • With the exception of the two combinations of conditional headers listed above, a request may specify only a single conditional header. Specifying more than one conditional header results in status code 400 (Bad Request).

  • If a response includes an ETag, verify the version of the request and response before processing the ETag. For example, version 2011-08-18 and later return a quoted ETag, but older versions do not. Ensure that your application can process both ETag formats before they are evaluated.

  • RFC 2616 allows multiple ETag values in a single header, but requests to the Blob service can only include one ETag value. Specifying more than one ETag value results in status code 400 (Bad Request).

Operations Supporting Conditional Headers

The operations that support conditional headers are described in the following table.

REST Operation Operation type Supported conditional headers
Append Block

(version 2015-02-21 and later)
Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Append Block From URL

(version 2018-11-09 and later)
Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Copy Blob Read and Write For conditions on the destination blob:

- If-Modified-Since

- If-Unmodified-Since

- If-Match

- If-None-Match

- x-ms-if-tags

For conditions on the source blob:

- x-ms-source-if-modified-since

- x-ms-source-if-unmodified-since

- x-ms-source-if-match

- x-ms-source-if-none-match

- x-ms-source-if-tags
Delete Blob Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Delete Container Write If-Modified-Since

If-Unmodified-Since
Get Blob Read If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Get Blob Metadata Read If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Get Blob Properties Read If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Get Blob Tags

(version 2019-12-12 and later)
Read x-ms-if-tags
Get Block List Read x-ms-if-tags
Get Page Ranges Read If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Lease Blob Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Lease Container Write If-Modified-Since

If-Unmodified-Since
Put Blob Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Put Block From URL

(version 2018-03-28 and later)
Write x-ms-source-If-Modified-Since

x-ms-source-If-Unmodified-Since

x-ms-source-If-Match

x-ms-source-If-None-Match
Put Block List Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Put Page Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Put Page From URL

(version 2018-11-09 and later)
Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Set Blob Metadata Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Set Blob Properties Write If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags
Set Container ACL Write If-Modified-Since

If-Unmodified-Since
Set Container Metadata Write If-Modified-Since
Set Blob Tags

(version 2019-12-12 and later)
Write x-ms-if-tags
Set Blob Tier Read or Write x-ms-if-tags
Snapshot Blob Read If-Modified-Since

If-Unmodified-Since

If-Match

If-None-Match

x-ms-if-tags

The following Blob service data operations do not currently support conditional headers:

HTTP Response Codes for Operations Supporting Conditional Headers

If the request includes a conditional header and the specified condition is not met by the resource being requested, the Blob service returns an HTTP response code. The response codes returned are in accordance with the HTTP/1.1 protocol specification (RFC 2616).

Methods in the Azure .NET client library convert these error response codes into a StorageException object.

Read Operations

The following table indicates the response codes returned for an unmet condition for each conditional header when the operation is a read operation. Read operations use the verbs GET or HEAD.

Conditional header Response code if condition has not been met
If-Modified-Since Not Modified (304 (Not Modified))
If-Unmodified-Since Precondition Failed (412 (Precondition Failed))
If-Match Precondition Failed (412 (Precondition Failed))
If-None-Match Not Modified (304 (Not Modified))

Refer to the examples above for results when using multiple headers with versions 2013-08-15 or later.

Write Operations

The following table indicates the response codes returned for an unmet condition for each conditional header when the operation is a write operation. Write operations use the verbs PUT or DELETE.

Conditional header Response code if condition has not been met
If-Modified-Since Precondition Failed (412 (Precondition Failed))
If-Unmodified-Since Precondition Failed (412 (Precondition Failed))
If-Match Precondition Failed (412 (Precondition Failed))
If-None-Match Precondition Failed (412 (Precondition Failed))

Copy Operations

The following table indicates the response codes returned for an unmet condition for each conditional header when the operation is a copy operation. The Copy Blob operation uses the verbs PUT.

Conditional header Response code if condition has not been met
If-Modified-Since Precondition Failed (412 (Precondition Failed))
If-Unmodified-Since Precondition Failed (412 (Precondition Failed))
If-Match Precondition Failed (412 (Precondition Failed))
If-None-Match Precondition Failed (412 (Precondition Failed))
x-ms-source-if-modified-since Precondition Failed (412 (Precondition Failed))
x-ms-source-if-unmodified-since Precondition Failed (412 (Precondition Failed))
x-ms-source-if-match Precondition Failed (412 (Precondition Failed))
x-ms-source-if-none-match Precondition Failed (412 (Precondition Failed))

Tags Conditional Operations

In addition to the standard HTTP conditional headers supported by the Blob service, several operations also support conditions against the tags on a blob resource.

Conditional header Description
x-ms-if-tags Version 2019-12-12 and newer. A TagsPredicate value. Specify this header to perform the operation only if the predicate evaluates to true against the blob's tags.
x-ms-source-if-tags Version 2019-12-12 and newer. Applies to Copy Blob only. A TagsPredicate value. Specify this header to perform the operation only if the predicate evaluates to true against the source blob's tags.

If the x-ms-if-tags or x-ms-source-if-tags conditional header is present in a request and the TagsPredicate evaluates to false, the Blob service will return error code 412 (Precondition Failed) for the operation.

The caller must have permission to read the tags on a blob to use the x-ms-if-tags or x-ms-source-if-tags conditional headers.

Tags Predicate Syntax

The Blob service supports a subset of the ANSI SQL WHERE clause grammar for the value of the TagsPredicate header. The following operators are supported:

Operator Description Example
= Equal Status = 'In Progress'
<> Not equal Status <> 'Done'
> Greater than LastModified > '2018-06-18 20:51:26Z'
>= Greater than or equal Priority >= '05'
< Less than Age < '032'
<= Less than or equal Reviewer <= 'Smith'
AND Logical and Name > 'C' AND Name < 'D'
Age > '032' AND Age < '100'
OR Logical or Status = 'Done' or LastModified > '2018-06-18 20:51:26Z'

All tag values are strings, and the supported binary relational operators use a lexicographic sorting of the tag values. To support non-string data types, including numbers and dates, appropriate padding and sortable formatting must be employed. Tag values must be enclosed in single quotes.

If tag names are regular SQL identifiers, they may be present without escaping; if they contain any special characters, they must be delimited with double quotes (e.g. "TagName" = 'TagValue').

Expressions may include comparisons for multiple tag names and values. Parenthesis (( and )) may be used to group logical expressions and control canonical order of operation. A TagsPredicate may include at most ten (10) logical operations.

The storage service will reject any request that contains an invalid expression with error code 400 (Bad Request).

See Also

Blob Service Concepts