When attempting to create a VM using a VHD that was previously used by a different VM, you may receive the following error:
A lease conflict occurred with the blob <blob url>
While these errors are expected if an existing VM is using a disk, we have identified an issue where a lease may remain even when no VM is using the blob.
If you receive this error, first make sure the VHD is not in use by a VM:
- In the Windows Azure management portal, if the disk shows up under Virtual Machines,
Disks, and the Attached To column is not blank, you should first remove that VM in the
Attached To column by going to VM Instances, selecting the VM, then clicking
Delete.
- If Attached To is blank, or the VM in the Attached To column was already removed, try removing the disk by highlighting it under
Disks and clicking Delete Disk (this will not physically delete the VHD from blob storage, it only removes the disk object in the portal). If you have multiple pages of disks it can be easier to search for a specific disk by
clicking the magnifying glass icon at the top right.
- If Delete Disk is grayed out, or the disk is not listed under Disks, but you still cannot reuse it or delete it, review the options below.
Breaking the lease
You can use the
Lease Blob API to break the lease in this scenario, which is also available in the Windows Azure PowerShell assembly
Microsoft.WindowsAzure.StorageClient.dll using
LeaseAction Enumeration.
A PowerShell script to break the lease is provided below. Mac and Linux users can use the
Node.js script for releasing a Windows Azure blob lease.
To use the BreakLease.ps1 script to break the lease:
- Download Azure PowerShell by clicking Install under Windows here:
http://www.windowsazure.com/en-us/manage/downloads/
- Start, Search, type Windows Azure PowerShell and open that console.
- Run Get-AzurePublishSettingsFile to launch a browser window to
https://windows.azure.com/download/publishprofile.aspx to download the management certificate in a
.publishsettings file in order to manage your subscription with PowerShell.
Get-AzurePublishSettingsFile
- Run Import-AzurePublishSettingsFile to import the certificate and subscription information. Replace the path below with the full path to the .publishsettings file if you didn't save it to your
Downloads folder. If you saved it to Downloads you can run it as-is, otherwise replace the path with the full path to the
.publishsettings file.
Import-AzurePublishSettingsfile $env:userprofile\downloads\*.publishsettings
- Copy the script below into a text editor such as Notepad and save it as
BreakLease.ps1.
- Run Set-ExecutionPolicy to allow script execution:
Set-ExecutionPolicy unrestricted
- Run BreakLease.ps1 with the URL to the VHD in order to break the lease. The script obtains the necessary storage account information, checks that the blob is not currently registered as a disk or as an image, then proceeds to break the
current lease (if any).
Sample output:
BreakLease.ps1 -Uri 'http://clstorage.blob.core.windows.net/vhds/testvm1-testvm1-2012-06-26.vhd'
Processing http://clstorage.blob.core.windows.net/vhds/testvm1-testvm1-2012-06-26.vhd
Reading storage account information...
Confirmed - storage account 'clstorage'.
Checking whether the blob is currently registered as a disk or image...
Confirmed - the blob is not in use by the Windows Azure platform.
Inspecting the blob's lease status...
Current lease status: Locked
Unlocking the blob...
Current lease status: Unlocked
Success - the blob is unlocked.
BreakLease.ps1
Param([string]$Uri = $(Read-Host -prompt "Please specify a blob URL"))
$ProgressPreference = 'SilentlyContinue'
echo "Processing $Uri"
echo "Reading storage account information..."
$acct = Get-AzureStorageAccount | ? { (new-object System.Uri($_.Endpoints[0])).Host -eq (new-object System.Uri($Uri)).Host }
if(-not $acct) {
write-host "The supplied URL does not appear to correspond to a storage account associated with the current subscription." -foregroundcolor "red"
break
}
$acctKey = Get-AzureStorageKey ($acct.StorageAccountName)
$creds = "DefaultEndpointsProtocol=http;AccountName=$($acctKey.StorageAccountName);AccountKey=$($acctKey.Primary)"
$acctobj = [Microsoft.WindowsAzure.CloudStorageAccount]::Parse($creds)
$uri = $acctobj.Credentials.TransformUri($uri)
echo "Confirmed - storage account '$($acct.StorageAccountName)'."
$blobclient = New-Object Microsoft.WindowsAzure.StorageClient.CloudBlobClient($acctobj.BlobEndpoint, $acctobj.Credentials)
$blobclient.Timeout = (New-TimeSpan -Minutes 1)
$blob = New-Object Microsoft.WindowsAzure.StorageClient.CloudPageBlob($uri, $blobclient)
echo "Checking whether the blob is currently registered as a disk or image..."
$disk = Get-AzureDisk | ? { (new-object System.Uri($_.MediaLink)) -eq $blob.Uri }
if($disk) {
write-host "The blob is still registered as a disk with name '$($disk.DiskName)'. Please delete the disk first." -foregroundcolor "red"
break
}
$image = Get-AzureVMImage | ? { $_.MediaLink -eq $blob.Uri.AbsoluteUri }
if($image) {
write-host "The blob is still registered as an OS image with name '$($image.ImageName)'. Please delete the OS image first." -foregroundcolor "red"
break
}
echo "Confirmed - the blob is not in use by the Windows Azure platform."
echo "Inspecting the blob's lease status..."
try {
$blob.FetchAttributes()
} catch [System.Management.Automation.MethodInvocationException] {
write-host $_.Exception.InnerException.Message -foregroundcolor "red"
break
}
echo "Current lease status: $($blob.Properties.LeaseStatus)"
if($blob.Properties.LeaseStatus -ne [Microsoft.WindowsAzure.StorageClient.LeaseStatus]::Locked) {
write-host "Success - the blob is unlocked." -foregroundcolor "green"
break
}
echo "Unlocking the blob..."
$request = [Microsoft.WindowsAzure.StorageClient.Protocol.BlobRequest]::Lease($uri, 0, [Microsoft.WindowsAzure.StorageClient.Protocol.LeaseAction]::Break, $null)
$request.Timeout = $blobclient.Timeout.TotalMilliseconds
$acctobj.Credentials.SignRequest($request)
try {
$response = $request.GetResponse()
$response.Close()
}
catch {
write-host "The blob could not be unlocked:" -foregroundcolor "red"
write-host $_.Exception.InnerException.Message -foregroundcolor "red"
break
}
$blob.FetchAttributes()
echo "Current lease status: $($blob.Properties.LeaseStatus)"
write-host "Success - the blob is unlocked." -foregroundcolor "green"
Alternate method: make a copy of the VHD in order to reuse a VHD with a stuck lease
If you have removed the VM and the disk object but the lease remains and you need to reuse that VHD, you can make a copy of the VHD and use the copy for a new VM:
- Download CloudXplorer. This will work with other
Windows Azure Storage Explorers but for the sake of brevity these steps will reference CloudXplorer.
- In the Windows Azure management portal, select Storage on the left, select the storage account where the VHD resides that you want to reuse, select
Manage Keys at the bottom, and copy the Primary Access Key.
- In CloudXplorer, go to File, Accounts,
New, Windows Azure Account and enter the storage account name in the
Name field and the primary access key in the Secret Key field. Leave the rest on the default settings.
- Expand the storage account in the left pane in CloudXplorer and select the
vhds container (or if the VHD in question is one uploaded to a different location, browse to that location instead).
- Right-click the VHD you want to reuse (which currently has a stuck lease), select
Rename, and give it a different name. This will throw the error
could not rename…there is currently a lease on the blob… but click
Yes to continue, then View, Refresh (F5) to refresh and you will see it did make a copy of the VHD since it could not rename the original.
- In the Azure management portal, select Virtual Machines,
Disks, then Create Disk at the bottom.
- Specify a name for the disk, click the folder icon under VHD URL to browse to the copy of the VHD you just created, check the box for
This VHD contains an operating system, select the drop-down to specify if it is
Windows or Linux, then click the arrow at the bottom right to create the disk.
- After the portal shows Successfully created disk <diskname>, select
New at the bottom left of the portal, then Virtual Machine,
From Gallery, My Disks, and select the disk you just created, then proceed through the rest of the wizard to create the VM.
Thanks,
Craig