Azure DMS SQL Server migration

Azure Database Migration Service - source database connectivity failure

Fix Azure Database Migration Service connectivity errors: verify NSG rules, firewall configuration, Self-Hosted Integration Runtime and source network setup.

·
Azure Database Migration Service aborts a migration task with "The connectivity check to the source server failed" or "Failed to connect to source SQL Server". Online or offline migration stops at the connection validation stage, preventing data transfer to Azure SQL Database. The problem most commonly stems from network configuration between the Self-Hosted Integration Runtime and the source SQL Server instance.

This runbook covers resolving DMS connectivity issues to the source SQL Server database. For a full guide on migrating .NET infrastructure to Azure, see Migrating .NET workloads to Azure - App Service, AKS, Landing Zone. For migration planning and execution support, book a consulting session.

Symptoms

DMS logs in Azure Portal or CLI show source database connection errors. The migration task remains in a “Failed” or “Stopped” state:

# Typical DMS error messages:
# "The connectivity check to the source server failed"
# "Failed to connect to source SQL Server. Reason: A network-related or instance-specific error occurred"
# "Login failed for user 'dms_migration_user'. Reason: The server is not configured to allow remote connections"
# "TCP Provider: No connection could be made because the target machine actively refused it"

# Check migration task status via Azure CLI
az dms project task show \
  --resource-group rg-migration \
  --service-name dms-prod-westeurope \
  --project-name sql-to-azure-project \
  --name full-migration-task \
  --query '{status:properties.state, errors:properties.errors}'

# List all tasks in the migration project
az dms project task list \
  --resource-group rg-migration \
  --service-name dms-prod-westeurope \
  --project-name sql-to-azure-project \
  --query '[].{name:name, state:properties.state}' -o table

# Check DMS events in Activity Log
az monitor activity-log list \
  --resource-group rg-migration \
  --start-time $(date -u -d '2 hours ago' +%Y-%m-%dT%H:%M:%SZ) \
  --query "[?contains(resourceId,'dms-prod-westeurope')].{time:eventTimestamp, status:status.value, message:properties.statusMessage}" \
  -o table

The task status is “Failed” with error code ConnectionFailure or SourceServerUnreachable. The Activity Log shows repeated failed connection attempts.

Cause

Azure DMS requires direct network communication with the source SQL Server instance (TCP port 1433 or a custom port). The connectivity error appears when:

  • NSG blocks port 1433: The Network Security Group assigned to the DMS subnet or the Self-Hosted IR subnet does not allow outbound traffic to the source SQL Server IP on port 1433. Default NSG rules block traffic to on-premises networks or peered VNets.

  • Source server firewall: Windows Firewall on the source SQL Server machine blocks inbound connections on port 1433. SQL Server may be configured to listen on a named instance (dynamic port) without a fixed port assignment.

  • Self-Hosted Integration Runtime is down: The SHIR agent on the intermediary machine is stopped, outdated, or has lost its connection to Azure. Without a functioning SHIR, DMS cannot reach resources in the on-premises network.

  • DNS resolution failure in the private network: DMS or SHIR cannot resolve the FQDN of the source SQL Server. Private DNS zones are not correctly configured or linked to the DMS VNet. The connection string uses a hostname that is unresolvable from the agent’s perspective.

  • Expired or incorrect credentials: The migration user’s password has expired, the account has been locked by a lockout policy, or the user lacks the db_datareader and VIEW SERVER STATE permissions required by DMS.

Fix

A) Verify and fix NSG rules:

# Find the NSG assigned to the DMS subnet
az network vnet subnet show \
  --resource-group rg-network \
  --vnet-name vnet-migration \
  --name subnet-dms \
  --query 'networkSecurityGroup.id' -o tsv

# List outbound NSG rules
az network nsg rule list \
  --resource-group rg-network \
  --nsg-name nsg-subnet-dms \
  --query "[?direction=='Outbound'].{name:name, priority:priority, access:access, destPort:destinationPortRange, destAddr:destinationAddressPrefix}" \
  -o table

# Add a rule allowing traffic to the source SQL Server (port 1433)
az network nsg rule create \
  --resource-group rg-network \
  --nsg-name nsg-subnet-dms \
  --name Allow-SQL-Source-Outbound \
  --priority 200 \
  --direction Outbound \
  --access Allow \
  --protocol Tcp \
  --source-address-prefixes "10.1.0.0/24" \
  --destination-address-prefixes "192.168.1.50" \
  --destination-port-ranges 1433 \
  --description "Allow DMS subnet to reach source SQL Server"

# If DMS connects via a peered VNet - check peering is active
az network vnet peering show \
  --resource-group rg-network \
  --vnet-name vnet-migration \
  --name peering-to-onprem-vnet \
  --query '{state:peeringState, allowForwarded:allowForwardedTraffic, useRemoteGw:useRemoteGateways}'

B) Configure the source server firewall:

# On the source SQL Server - check if port 1433 is open
Test-NetConnection -ComputerName localhost -Port 1433

# Add a Windows Firewall rule for port 1433
New-NetFirewallRule `
  -DisplayName "Allow DMS Inbound SQL" `
  -Direction Inbound `
  -Protocol TCP `
  -LocalPort 1433 `
  -Action Allow `
  -RemoteAddress 10.1.0.0/24 `
  -Description "Allow Azure DMS subnet to connect to SQL Server"

# Check if SQL Server is listening on TCP and the correct port
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQLServer\SuperSocketNetLib\Tcp" `
  -Name Enabled

# For a named instance - assign a static port in SQL Server Configuration Manager
# SQL Server Configuration Manager > SQL Server Network Configuration >
# Protocols for [INSTANCE] > TCP/IP > IP Addresses > IPAll > TCP Port = 1433

# Restart the SQL Server service after changing the port
Restart-Service -Name 'MSSQL$MSSQLSERVER' -Force

# Verify listening state
Get-NetTCPConnection -LocalPort 1433 -State Listen

C) Fix the Self-Hosted Integration Runtime:

# On the SHIR machine - check service status
Get-Service -Name "DIAHostService" | Select-Object Status, StartType

# If the service is stopped - start it
Start-Service -Name "DIAHostService"

# Check SHIR version and whether it needs an update
& "C:\Program Files\Microsoft Integration Runtime\5.0\Shared\dmgcmd.exe" -Status
# From Azure CLI - check SHIR state (Integration Runtime)
az datafactory integration-runtime show \
  --resource-group rg-migration \
  --factory-name adf-migration-prod \
  --name shir-onprem-agent \
  --query '{state:properties.state, version:properties.version, autoUpdate:properties.autoUpdate}'

# If SHIR is in "NeedRegistration" state - re-register
# 1. Retrieve a new key from the portal or CLI:
az datafactory integration-runtime list-auth-key \
  --resource-group rg-migration \
  --factory-name adf-migration-prod \
  --name shir-onprem-agent \
  --query 'authKey1' -o tsv
# 2. On the SHIR machine - register with the new key
& "C:\Program Files\Microsoft Integration Runtime\5.0\Shared\dmgcmd.exe" `
  -RegisterNewNode "IR@xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx@adf-migration-prod@ServiceEndpoint=https://westeurope.svc.datafactory.azure.net/"

# 3. Test the connection to SQL Server through SHIR
& "C:\Program Files\Microsoft Integration Runtime\5.0\Shared\dmgcmd.exe" `
  -TestConnection "Data Source=192.168.1.50,1433;Initial Catalog=SourceDB;User ID=dms_migration_user;Password=***;Encrypt=False;TrustServerCertificate=True"

D) Resolve DNS and credential issues:

# Check DNS resolution from the SHIR or a VM in the DMS subnet
nslookup sql-source.corp.local
# If it does not resolve - add an entry in Private DNS Zone or hosts file

# Check whether the Private DNS Zone is linked to the DMS VNet
az network private-dns zone list \
  --query "[].{name:name, vnetLinks:numberOfVirtualNetworkLinks}" -o table

az network private-dns link vnet list \
  --resource-group rg-dns \
  --zone-name corp.local \
  --query "[].{name:name, vnetId:virtualNetwork.id, registrationEnabled:registrationEnabled}" -o table

# If the link is missing - add the DMS VNet to the Private DNS Zone
az network private-dns link vnet create \
  --resource-group rg-dns \
  --zone-name corp.local \
  --name link-vnet-migration \
  --virtual-network /subscriptions/<sub-id>/resourceGroups/rg-network/providers/Microsoft.Network/virtualNetworks/vnet-migration \
  --registration-enabled false
# Verify credentials - attempt a connection to SQL Server
# On the SHIR machine or any machine in the network:
Invoke-Sqlcmd -ServerInstance "192.168.1.50,1433" `
  -Database "SourceDB" `
  -Username "dms_migration_user" `
  -Password "CurrentPassword123!" `
  -Query "SELECT 1 AS connectivity_test" `
  -TrustServerCertificate

# If login fails - reset the password on the source SQL Server
Invoke-Sqlcmd -ServerInstance "192.168.1.50,1433" `
  -Database "master" `
  -Username "sa" `
  -Password "SaPassword!" `
  -Query "ALTER LOGIN dms_migration_user WITH PASSWORD = 'NewSecurePassword456!';" `
  -TrustServerCertificate

# Ensure the user has the permissions required by DMS
Invoke-Sqlcmd -ServerInstance "192.168.1.50,1433" `
  -Database "master" `
  -Username "sa" `
  -Password "SaPassword!" `
  -Query @"
GRANT VIEW SERVER STATE TO [dms_migration_user];
USE [SourceDB];
EXEC sp_addrolemember 'db_datareader', 'dms_migration_user';
GRANT VIEW DATABASE STATE TO [dms_migration_user];
"@ `
  -TrustServerCertificate

After fixing the root cause - update the connection string in the DMS project and restart the task:

# Restart the migration task after fixing connectivity
az dms project task restart \
  --resource-group rg-migration \
  --service-name dms-prod-westeurope \
  --project-name sql-to-azure-project \
  --name full-migration-task

Verification

# 1. Test network connectivity from the DMS subnet (from a diagnostic VM or SHIR)
# On a machine in the DMS subnet:
Test-NetConnection -ComputerName 192.168.1.50 -Port 1433
# Expected: TcpTestSucceeded = True
# 2. Check DMS task status after restart
az dms project task show \
  --resource-group rg-migration \
  --service-name dms-prod-westeurope \
  --project-name sql-to-azure-project \
  --name full-migration-task \
  --query '{state:properties.state, migrationType:properties.taskType}' -o json
# Expected: state = "Running" or "Succeeded"

# 3. Check migration progress (number of migrated tables)
az dms project task show \
  --resource-group rg-migration \
  --service-name dms-prod-westeurope \
  --project-name sql-to-azure-project \
  --name full-migration-task \
  --query 'properties.output[?resultType==`MigrationLevelOutput`].{status:migrationState, startedOn:startedOn, tables:summary.tableCount}' \
  -o table
# Expected: migrationState = "MIGRATION_IN_PROGRESS" or "MIGRATION_COMPLETED"

# 4. Verify SHIR connectivity
az datafactory integration-runtime show \
  --resource-group rg-migration \
  --factory-name adf-migration-prod \
  --name shir-onprem-agent \
  --query 'properties.state' -o tsv
# Expected: "Online"

# 5. Verify data is flowing to Azure SQL Database
az sql db show \
  --resource-group rg-azure-sql \
  --server sql-target-prod \
  --name TargetDB \
  --query '{status:status, currentSku:currentSku.name, size:maxSizeBytes}' -o json

If the DMS task is in a “Running” or “Succeeded” state, network connectivity works (TcpTestSucceeded = True), and the SHIR is “Online” - the problem is resolved. Monitor migration progress until all tables have been transferred.

A DMS connectivity failure halts the entire database migration process. For online migrations (with continuous replication) - a connectivity break means loss of CDC synchronisation and the need for a full data reload. For large databases (>100 GB) this adds hours or days of delay. In a weekend cutover scenario - losing the migration window can force a week-long postponement or more, directly impacting the project timeline and team costs.

 

Jerzy Kopaczewski

SQL Server migration to Azure not going to plan?

Book a free 30-minute call. We'll review your DMS configuration, network setup and Integration Runtime to unblock the migration and meet your cutover deadline.