I recently encountered a deployment failure when provisioning a new SQL Server 2025 VM based on a Windows Server 2025 image in Azure.

The VM size was E2ds_v6, which includes ~110 GB local storage (NVMe / ephemeral).
The deployment failed during provisioning with this error:
{
"status": "Failed",
"error": {
"code": "Ext_StorageConfigurationSettings_ApplyNewTempDbSettingsError",
"message": "Error: 'System Drive returned status not ready for use '"
}
What was happening
In my case, the root cause was surprisingly simple: the local NVMe disk was presented to Windows as RAW / uninitialized.

The SQL Server IaaS extension (the component Azure uses to apply storage configuration for SQL on a VM) tried to configure tempdb on that local disk. Because the disk had no partition, no file system, and no drive letter, the extension step failed, and the entire provisioning process ended as Failed.
This is especially annoying because local/ephemeral disks are exactly where you often want tempdb (fast IOPS), but only if the disk is actually usable at boot time.
The fix: initialize the NVMe temp disk at startup (idempotent script)
The solution that worked for me was to create a PowerShell script that runs on startup and does the following:
- Find the first non-OS NVMe disk ( you can edit it to get the drive based on name or a different attribute, as per your current setup)
- If it is RAW, initialize it (GPT), create one partition, and format it NTFS
- Force the drive letter to T: (so my tempdb path is stable)
- Create the folder T:\SQLTemp
- Grant permissions to the default instance service SID: NT SERVICE\MSSQLSERVER
Here is the script exactly as I used it:
# Pick the temp NVMe disk: non-OS, NVMe bus, and possibly RAW
$disk = Get-Disk | Where-Object {
$_.IsBoot -eq $false -and $_.IsSystem -eq $false -and $_.BusType -eq 'NVMe'
} | Sort-Object Number | Select-Object -First 1
if ($null -eq $disk) { exit 0 }
# If RAW, initialize + partition + format and force drive letter T:
if ($disk.PartitionStyle -eq 'RAW') {
Initialize-Disk -Number $disk.Number -PartitionStyle GPT -PassThru | Out-Null
$part = New-Partition -DiskNumber $disk.Number -UseMaximumSize -DriveLetter T
Format-Volume -Partition $part -FileSystem NTFS -NewFileSystemLabel "TEMP" -AllocationUnitSize 65536 -Confirm:$false | Out-Null
}
# If it’s already formatted but missing letter T, try to assign it
$vol = Get-Volume | Where-Object { $_.FileSystemLabel -eq 'TEMP' } | Select-Object -First 1
if ($vol -and $vol.DriveLetter -ne 'T') {
Set-Partition -DriveLetter $vol.DriveLetter -NewDriveLetter T
}
# Ensure TempDB folder exists
$tempFolder = "T:\SQLTemp"
if (!(Test-Path $tempFolder)) { New-Item -ItemType Directory -Path $tempFolder | Out-Null }
# Grant SQL Server service account (default instance service SID) rights
icacls $tempFolder /grant "NT SERVICE\MSSQLSERVER:(OI)(CI)F" /T | Out-Null
# Start SQL
Start-Service "MSSQLSERVER"
Start-Service "SQLSERVERAGENT" -ErrorAction SilentlyContinue
Important detail: make sure SQL Server doesn’t start before the disk is ready
Just initializing the disk is not enough if SQL Server starts too early.
- Set the SQL Server (MSSQLSERVER) service startup type from Automatic to Manual
- Set the SQL Server Agent (MSSQLSERVER) service startup type from Automatic to Manual
Then create a new Windows Task (use Task Scheduler) to be run at system startup:
- Trigger: At startup
- Security options: Run whether the user is logged on or not
- Security options: Run with highest privileges
- Action:
powershell.exe - Arguments:
-ExecutionPolicy Bypass -File C:\Scripts\Init-TempDisk-AndStartSql.ps1
After a reboot, the VM brought up the temp drive first, then SQL Server came online cleanly. The deployment succeeded, and tempdb could be placed where it belongs.
Alternative options (if you don’t want tempdb on local storage)
If you want a simpler/safer setup (at the cost of I/O), you can avoid placing tempdb on ephemeral storage entirely:
- Use a VM size where the temp disk is presented consistently and already formatted
- Place tempdb on a managed data disk (Premium SSD / Ultra Disk) and configure it that way from the start.
Important note: How SQL IaaS starts SQL Server (and why you should not edit its startup task)
When you deploy a SQL Server VM from the Azure Marketplace image, Azure installs the SQL Server IaaS Agent extension. One of the things this extension does is create a Windows Scheduled Task (running at system startup) that executesSqlIaaSExtension.SqlServerStarter.exe. This starter component is responsible for bringing the SQL Server services online in a predictable way (and for some configurations, it also validates or prepares required paths used by SQL Server).
A key detail is that this scheduled task is managed by the SQL IaaS extension. That means it is effectively treated as “desired state”: on every VM boot, the extension can recreate or reset the task to its default definition. Because of that, any manual edits (for example, adding a PowerShell step into the same task) are not persistent. If you add your PowerShell action directly into the SQL IaaS startup task, it will typically be deleted on the next VM startup, because the extension rewrites the task back to the default version.
The correct approach is to leave the SQL IaaS task untouched and create a separate startup scheduled task for your own script (for example, to initialize and format the ephemeral NVMe disk and create T:\SQLTemp). Your task can run at startup and ensure the drive and folder exist, and then (optionally) start or restart the SQL Server service if needed.
