Description
Azurite returns 412 ConditionNotMet when HEAD or GET targets a missing blob with If-Match set to a valid ETag obtained from another blob. Azure Blob Storage returns 404 BlobNotFound for the same requests.
This prevents clients and compatibility tests from distinguishing a missing blob from an existing blob whose ETag does not match.
Reproduction
Tested with:
mcr.microsoft.com/azure-storage/azurite:3.37.0
- Also reproduced with Azurite 3.35.0
x-ms-version: 2022-11-02
- Raw Shared Key REST requests
Steps:
- Create a container.
- Create blob A and save the ETag returned by Azurite.
- Choose a different blob name B that does not exist in the same container.
- Send
HEAD for blob B with If-Match: <etag-from-blob-A>.
- Send
GET for blob B with the same If-Match value.
The ETag must be a valid value returned by the service. A synthetic malformed ETag is not an equivalent reproduction because Azure Storage can reject it as a failed condition.
Actual behavior
| Service |
HEAD missing blob |
GET missing blob |
| Azurite 3.37.0 |
412 ConditionNotMet |
412 ConditionNotMet |
| Azurite 3.35.0 |
412 ConditionNotMet |
412 ConditionNotMet |
Azurite 3.37.0 request IDs from one reproduction:
- HEAD:
5d0c1796-dce8-44a9-a8cc-d531185ac35b
- GET:
c51e7848-072a-4405-9307-aaced86f9b70
Expected behavior
Match Azure Blob Storage and return 404 BlobNotFound for both requests because blob B does not exist.
The same raw requests against the live Azure Blob Storage service returned:
| Service |
HEAD missing blob |
GET missing blob |
| Azure Blob Storage |
404 BlobNotFound |
404 BlobNotFound |
Azure request IDs from the control reproduction:
- HEAD:
b7fcf34d-c01e-000d-26ff-35582f000000
- GET:
067d7966-601e-0014-38ff-35d894000000
Impact
Clients that expose missing-target and conditional-mismatch results separately cannot run the same conditional read tests against Azurite and Azure Storage. A client-side existence check is not a suitable compatibility workaround because it adds another request and introduces a race.
AI assisted with the live-service comparison and drafting. The submitter directed the scope and conclusion.
Description
Azurite returns
412 ConditionNotMetwhenHEADorGETtargets a missing blob withIf-Matchset to a valid ETag obtained from another blob. Azure Blob Storage returns404 BlobNotFoundfor the same requests.This prevents clients and compatibility tests from distinguishing a missing blob from an existing blob whose ETag does not match.
Reproduction
Tested with:
mcr.microsoft.com/azure-storage/azurite:3.37.0x-ms-version: 2022-11-02Steps:
HEADfor blob B withIf-Match: <etag-from-blob-A>.GETfor blob B with the sameIf-Matchvalue.The ETag must be a valid value returned by the service. A synthetic malformed ETag is not an equivalent reproduction because Azure Storage can reject it as a failed condition.
Actual behavior
412 ConditionNotMet412 ConditionNotMet412 ConditionNotMet412 ConditionNotMetAzurite 3.37.0 request IDs from one reproduction:
5d0c1796-dce8-44a9-a8cc-d531185ac35bc51e7848-072a-4405-9307-aaced86f9b70Expected behavior
Match Azure Blob Storage and return
404 BlobNotFoundfor both requests because blob B does not exist.The same raw requests against the live Azure Blob Storage service returned:
404 BlobNotFound404 BlobNotFoundAzure request IDs from the control reproduction:
b7fcf34d-c01e-000d-26ff-35582f000000067d7966-601e-0014-38ff-35d894000000Impact
Clients that expose missing-target and conditional-mismatch results separately cannot run the same conditional read tests against Azurite and Azure Storage. A client-side existence check is not a suitable compatibility workaround because it adds another request and introduces a race.
AI assisted with the live-service comparison and drafting. The submitter directed the scope and conclusion.