{"record":{"id":"750c91c43dec6138","repo":"hashicorp/terraform","slug":"error-snapshotting-blob-q-container-q-account","errorCode":null,"errorMessage":"error snapshotting Blob %q (Container %q / Account %q): %+v","messagePattern":"error snapshotting Blob %q \\(Container %q / Account %q\\): %\\+v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/azure/client.go","lineNumber":102,"sourceCode":"\tsetOptions := blobs.SetPropertiesInput{}\n\tputOptions := blobs.PutBlockBlobInput{}\n\n\toptions := blobs.GetInput{}\n\tif c.leaseID != \"\" {\n\t\toptions.LeaseID = &c.leaseID\n\t\tgetOptions.LeaseID = &c.leaseID\n\t\tsetOptions.LeaseID = &c.leaseID\n\t\tputOptions.LeaseID = &c.leaseID\n\t}\n\n\tctx := newCtx()\n\n\tif c.snapshot {\n\t\tsnapshotInput := blobs.SnapshotInput{LeaseID: options.LeaseID}\n\n\t\tlog.Printf(\"[DEBUG] Snapshotting existing Blob %q (Container %q / Account %q)\", c.keyName, c.containerName, c.accountName)\n\t\tif _, err := c.giovanniBlobClient.Snapshot(ctx, c.containerName, c.keyName, snapshotInput); err != nil {\n\t\t\treturn diags.Append(fmt.Errorf(\"error snapshotting Blob %q (Container %q / Account %q): %+v\", c.keyName, c.containerName, c.accountName, err))\n\t\t}\n\n\t\tlog.Print(\"[DEBUG] Created blob snapshot\")\n\t}\n\n\tblob, err := c.giovanniBlobClient.GetProperties(ctx, c.containerName, c.keyName, getOptions)\n\tif err != nil {\n\t\tif !response.WasNotFound(blob.HttpResponse) {\n\t\t\treturn diags.Append(err)\n\t\t}\n\t}\n\n\tcontentType := \"application/json\"\n\tputOptions.Content = &data\n\tputOptions.ContentType = &contentType\n\tputOptions.MetaData = blob.MetaData\n\t_, err = c.giovanniBlobClient.PutBlockBlob(ctx, c.containerName, c.keyName, putOptions)\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/azure/client.go#L84-L120","documentation":"Raised in RemoteClient.Put (client.go:97-103) when the backend's snapshot feature is enabled (snapshot = true / ARM_SNAPSHOT=true). Before overwriting the state blob, Terraform snapshots the existing blob for point-in-time recovery; if the Giovanni Snapshot data-plane call fails, this error (with key/container/account context) is returned and the state write aborts to avoid losing the snapshot trail.","triggerScenarios":"Produced at client.go:101-103 when c.snapshot is true and c.giovanniBlobClient.Snapshot(ctx, containerName, keyName, snapshotInput) returns an error during a state write (terraform apply/refresh that persists state).","commonSituations":"The blob is lease-locked by another process so Snapshot cannot proceed; the storage account/replication does not support snapshots; the blob was deleted between GetProperties and Snapshot; data-plane permission lacks 'create' for snapshot; transient storage service error.","solutions":["Ensure no other process holds a lease on the state blob during apply","Confirm the credential has 'Storage Blob Data Contributor' (data-plane) permission","Retry — transient storage errors often resolve on the next run","If snapshots are unsupported by your account tier/replication, set snapshot = false"],"exampleFix":"# before: snapshot enabled but write fails under contention\nterraform {\n  backend \"azurerm\" {\n    storage_account_name = \"mystage\"\n    snapshot             = true\n    ...\n  }\n}\n\n# after: disable snapshot if unsupported, or serialize runs\nterraform {\n  backend \"azurerm\" {\n    storage_account_name = \"mystage\"\n    snapshot             = false\n    ...\n  }\n}\n# ensure only one terraform apply runs at a time per workspace","handlingStrategy":"retry","validationCode":"# Confirm the state blob is not lease-locked before an apply with snapshot=true\nSTATUS=$(az storage blob show --account-name \"$ARM_STORAGE_ACCOUNT_NAME\" -c \"$ARM_CONTAINER_NAME\" -n \"$ARM_KEY\" --query 'properties.lease.status' -o tsv 2>/dev/null)\n[ \"$STATUS\" = \"locked\" ] && echo \"WARN: blob locked -> snapshot may fail (153)\" || echo \"OK: writable\"","typeGuard":null,"tryCatchPattern":"# Retry transient snapshot failures with bounded backoff\napply_with_snapshot() {\n  for attempt in 1 2 3; do\n    if terraform apply -auto-approve; then return 0; fi\n    grep -q \"error snapshotting Blob\" && sleep $((attempt*5)) || return 1\n  done\n  echo \"snapshot keeps failing; consider snapshot=false or serialize runs\"\n  return 1\n}","preventionTips":["Serialize terraform apply per workspace to avoid lease contention during snapshot","If your account tier/replication rejects snapshots, set snapshot = false","Ensure data-plane write permission for the credential"],"tags":["azure","storage","snapshot","state","write"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}