AZURE

PreconditionFailed - Precondition Failed: Conditional Header Failed

Your conditional header condition failed—the If-Match ETag doesn't match the current resource ETag, If-None-Match: * failed because the resource exists, or If-Modified-Since timestamp is outdated. This 412 client-side error means ARM's optimistic concurrency control rejected the operation to prevent lost updates. ARM compares your conditional header value against the current resource state; mismatches indicate concurrent modifications happened between your read and write operations. ETags change immediately when resources are modified, so concurrent updates cause mismatches. Common in VM updates, AKS cluster modifications, Azure SQL database changes, and App Service configuration updates.

#Common Causes

  • ETag Mismatch: The resource ETag changed between read and write operations. Your If-Match header value doesn't match the current resource.etag, indicating another operation modified the resource concurrently. ARM updates ETags immediately when resources change, so concurrent modifications cause ETag mismatches.
  • Resource Already Exists: Using If-None-Match: * prevents overwriting existing resources. Your request includes If-None-Match: * which ensures you're creating a new resource, not overwriting an existing one. If the resource already exists, the condition fails.
  • Resource Modified After Timestamp: The resource's lastModified timestamp is greater than your If-Modified-Since header value. The resource was modified after the timestamp you specified. This occurs with conditional GET requests.

Solutions

  1. 1Step 1: Diagnose - Get fresh ETag from current resource state. For Storage blobs: az storage blob show --container-name <container> --name <blob> --account-name <account> --query "properties.etag" --output table
  2. 2Step 2: Diagnose - Check resource properties to understand what changed: az storage blob show --container-name <container> --name <blob> --account-name <account> --query "{etag:properties.etag, lastModified:properties.lastModified}" --output table
  3. 3Step 3: Fix - Retry with fresh ETag using the read-modify-write pattern: GET the resource, modify it, then PUT with the fresh ETag.
  4. 4Step 4: Fix - If using If-None-Match: *, remove the header if you want to allow overwrites, or use a different resource name.
  5. 5Step 5: Fix - Use a more recent timestamp for If-Modified-Since, or get the current resource state.
  6. 6Step 6: Verify - Retry your operation with the fresh ETag. It should succeed with HTTP 200/201 instead of 412 PreconditionFailed.

</>Code Examples

ETag Management and Retry Logic
1# This script helps diagnose PreconditionFailed errors by managing ETags
2
3# Step 1: Set storage account details (replace with your values)
4STORAGE_ACCOUNT="mystorageaccount"
5CONTAINER_NAME="mycontainer"
6BLOB_NAME="myblob.txt"
7# Note: For production, use Azure Key Vault or managed identity instead of account key
8ACCOUNT_KEY="your-storage-account-key"
9
10# Step 2: Get current ETag from blob
11echo "Getting current ETag from blob..."
12CURRENT_ETAG=$(az storage blob show \
13  --container-name $CONTAINER_NAME \
14  --name $BLOB_NAME \
15  --account-name $STORAGE_ACCOUNT \
16  --account-key $ACCOUNT_KEY \
17  --query "properties.etag" \
18  --output tsv)
19
20if [ ! -z "$CURRENT_ETAG" ]; then
21  echo "Current ETag: $CURRENT_ETAG"
22else
23  echo "Blob not found or inaccessible"
24  exit 1
25fi
26
27# Step 3: Get resource properties to understand what changed
28echo "Getting blob properties..."
29az storage blob show \
30  --container-name $CONTAINER_NAME \
31  --name $BLOB_NAME \
32  --account-name $STORAGE_ACCOUNT \
33  --account-key $ACCOUNT_KEY \
34  --query "{etag:properties.etag, lastModified:properties.lastModified, contentLength:properties.contentLength}" \
35  --output table
36
37# Step 4: Retry function with ETag refresh
38retry_with_etag() {
39  local max_attempts=$1
40  local attempt=1
41  shift 1
42  
43  while [ $attempt -le $max_attempts ]; do
44    echo "Attempt $attempt of $max_attempts..."
45    
46    # Get fresh ETag before each attempt
47    FRESH_ETAG=$(az storage blob show \
48      --container-name $CONTAINER_NAME \
49      --name $BLOB_NAME \
50      --account-name $STORAGE_ACCOUNT \
51      --account-key $ACCOUNT_KEY \
52      --query "properties.etag" \
53      --output tsv)
54    
55    echo "Using ETag: $FRESH_ETAG"
56    
57    # Perform operation with fresh ETag
58    # Note: Azure CLI doesn't directly support If-Match headers
59    # You would need to use REST API or SDK for conditional operations
60    # This is a demonstration of the pattern
61    
62    if [ $attempt -lt $max_attempts ]; then
63      echo "Waiting before retry..."
64      sleep 1
65      attempt=$((attempt + 1))
66    else
67      echo "Max attempts reached"
68      break
69    fi
70  done
71}
72
73# Step 5: Instructions for using ETags with REST API
74echo ""
75echo "To use ETags with conditional headers:"
76echo "  1. GET the resource to obtain current ETag"
77echo "  2. Include If-Match header with the ETag in your update request"
78echo "  3. If you get 412 PreconditionFailed, GET the resource again for fresh ETag"
79echo "  4. Retry the update with the fresh ETag"
80echo ""
81echo "Example REST API call with If-Match:"
82echo "  PUT /subscriptions/{sub-id}/resourceGroups/{rg}/providers/..."
83echo "  Headers:"
84echo "    If-Match: "$CURRENT_ETAG""
85echo "    Authorization: Bearer <token>"

Related Errors

Provider Information

This error code is specific to AZURE services. For more information, refer to the official AZURE documentation.

PreconditionFailed - Precondition Failed: Conditional Header Failed | AZURE Error Reference | Error Code Reference