AZ-104 Study Material
Troubleshooting Case Studies
12 real-world Azure administrator break/fix scenarios — symptoms, diagnostics, correct fix, and exam takeaway for each.
VM Cannot Be Reached via RDP/SSH
Admin cannot connect to Windows VM. VM is running. Public IP assigned.
| Step | Check | Tool |
|---|---|---|
| ------ | ------- | ------ |
| 1 | Is NSG allowing inbound 3389/22? | VM → Networking → NSG rules |
| 2 | Is VM in Running state (not deallocated)? | Portal VM overview |
| 3 | Is public IP associated with NIC? | VM → Networking |
| 4 | Is Windows Firewall blocking on guest OS? | Run Command / serial console |
| 5 | Is Bastion required (no public IP)? | Use Bastion connect instead |
# Add NSG rule for RDP az network nsg rule create -g rg-compute --nsg-name nsg-vm \ -n Allow-RDP --priority 100 --direction Inbound \ --access Allow --protocol Tcp --destination-port-ranges 3389 \ --source-address-prefixes <admin-ip>/32 # Verify effective NSG rules az network nic list-effective-nsg -g rg-compute -n vm-nic-name
Storage Account Access Denied from VM
Application on VM receives 403 Forbidden when accessing blob storage.
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Storage firewall: is VM subnet/IP allowed? |
| 2 | Is allowBlobPublicAccess disabled (expected)? |
| 3 | Does managed identity have Blob Data role? |
| 4 | If using key/SAS: expired or wrong permissions? |
| 5 | Private Endpoint: does DNS resolve to private IP? |
# Add VM subnet to storage firewall az storage account network-rule add \ --account-name stcontoso001 \ --resource-group rg-storage \ --subnet /subscriptions/<sub>/resourceGroups/rg-compute/providers/Microsoft.Network/virtualNetworks/vnet-prod/subnets/snet-app # Or add single IP az storage account network-rule add \ --account-name stcontoso001 \ --resource-group rg-storage \ --ip-address 10.0.1.4
Private Endpoint DNS Resolution Fails
VM resolves `stcontoso.blob.core.windows.net` to public IP (20.x.x.x) instead of private IP (10.x.x.x).
Work through NSG rules, resource state, DNS, and RBAC in order.
# Create Private DNS zone az network private-dns zone create -g rg-storage -n privatelink.blob.core.windows.net # Link to VNet az network private-dns link vnet create -g rg-storage \ --zone-name privatelink.blob.core.windows.net \ --name blob-link --virtual-network vnet-prod --registration-enabled false # Add DNS zone group to existing private endpoint az network private-endpoint dns-zone-group create \ -g rg-storage --endpoint-name pe-blob \ --name default --private-dns-zone privatelink.blob.core.windows.net \ --zone-name blob # Verify from VM nslookup stcontoso.blob.core.windows.net # Should return 10.x.x.x (private IP)
VNet Peering Shows "Connected" but No Connectivity
VNet A and VNet B show peering status "Connected" but VMs cannot ping each other.
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Address spaces overlap? (peering fails if overlapping) |
| 2 | allowVirtualNetworkAccess enabled on both peerings? |
| 3 | NSG blocking traffic on source or destination subnet? |
| 4 | UDR routing traffic to blackhole or firewall? |
| 5 | Trying transitive peering (A→B→C)? |
az network vnet peering update -g rg-net -n vnet-a-to-b \ --vnet-name vnet-a --set allowVirtualNetworkAccess=true az network vnet peering update -g rg-net -n vnet-b-to-a \ --vnet-name vnet-b --set allowVirtualNetworkAccess=true
Azure Bastion Deployment Fails
Bastion creation fails with subnet validation error.
Work through NSG rules, resource state, DNS, and RBAC in order.
Symptoms: Bastion creation fails with subnet validation error.
Common causes and fixes:
| Error | Cause | Fix |
|---|---|---|
| ------- | ------- | ----- |
| Subnet name invalid | Named "BastionSubnet" instead of AzureBastionSubnet | Rename subnet exactly |
| Subnet too small | /27 or /28 | Resize to /26 minimum |
| NSG on Bastion subnet | NSG associated with AzureBastionSubnet | Remove NSG from subnet |
| No Standard public IP | Basic SKU public IP used | Create Standard SKU public IP |
| Subnet has other resources | Gateway or VM in Bastion subnet | Dedicated subnet for Bastion only |
VPN Tunnel Shows "Not Connected"
Site-to-site VPN connection status is "Not Connected" or "Updating".
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Shared key matches on both sides? |
| 2 | On-premises public IP correct in Local Network Gateway? |
| 3 | On-premises address spaces correct? |
| 4 | VPN Gateway fully provisioned (takes 30-45 min)? |
| 5 | On-premises firewall allows UDP 500, 4500, ESP? |
| 6 | IKE/IPsec policy compatible? |
Symptoms: Site-to-site VPN connection status is "Not Connected" or "Updating".
Diagnostic checklist:
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Shared key matches on both sides? |
| 2 | On-premises public IP correct in Local Network Gateway? |
| 3 | On-premises address spaces correct? |
| 4 | VPN Gateway fully provisioned (takes 30-45 min)? |
| 5 | On-premises firewall allows UDP 500, 4500, ESP? |
| 6 | IKE/IPsec policy compatible? |
Tools:
# VPN troubleshoot via Network Watcher az network watcher vpn-gateway troubleshoot \ --resource-group rg-net --gateway-name vpngw-hub # Check connection status az network vpn-connection show -g rg-net -n conn-onprem --query connectionStatus
VM Backup Failing
Azure Backup job shows "Failed" for VM protection.
Work through NSG rules, resource state, DNS, and RBAC in order.
Symptoms: Azure Backup job shows "Failed" for VM protection.
Common causes:
| Cause | Fix |
|---|---|
| ------- | ----- |
| VM agent not installed/outdated | Install/update Azure VM agent |
| VM locked or being modified | Retry after VM stable |
| Snapshot limit exceeded | Check disk snapshot quotas |
| Vault in different region without GRS | Use GRS vault for cross-region |
| Encryption conflict | Ensure Key Vault accessible for encrypted VMs |
| Extension conflict | Check guest OS for conflicting backup agents |
# Check backup job errors az backup job list --resource-group rg-backup --vault-name rsv-backup-01 \ --query "[?properties.status=='Failed']" -o table # Re-register VM if agent issue az backup protection enable-for-vm \ --resource-group rg-backup --vault-name rsv-backup-01 \ --vm vm-web-01 --policy-name DailyPolicy --force
Entra Connect Sync Not Working
New on-premises users not appearing in Entra ID after 2+ hours.
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Connect server running? Sync service started? |
| 2 | User in correct OU (not filtered out)? |
| 3 | User has required attributes (UPN, displayName)? |
| 4 | Duplicate UPN or proxyAddresses conflict? |
| 5 | Staging mode enabled (not exporting)? |
# On Connect server Import-Module ADSync Start-ADSyncSyncCycle -PolicyType Delta # Check sync errors Get-ADSyncConnectorRunStatus
App Service Cannot Reach SQL Database
Web app returns database connection errors. SQL Database firewall configured.
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | "Allow Azure services" enabled on SQL firewall? (quick fix, less secure) |
| 2 | VNet integration configured on App Service? |
| 3 | Private Endpoint for SQL with correct DNS? |
| 4 | Connection string uses correct server name? |
| 5 | Managed identity granted access to SQL? |
-- On SQL Database (as Azure AD admin) CREATE USER [app-contoso] FROM EXTERNAL PROVIDER; ALTER ROLE db_datareader ADD MEMBER [app-contoso]; ALTER ROLE db_datawriter ADD MEMBER [app-contoso];
# Enable system-assigned identity on App Service az webapp identity assign -g rg-app -n app-contoso
Metric Alert Not Firing
CPU exceeded 90% but no alert email received.
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Alert rule enabled? |
| 2 | Threshold and aggregation correct (avg vs max)? |
| 3 | Evaluation period and frequency appropriate? |
| 4 | Action group email correct and not in spam? |
| 5 | Alert in fired state but action group failed? |
| 6 | Resource sending metrics (agent installed)? |
# Check alert history az monitor metrics alert list -g rg-monitor -o table # Test action group az monitor action-group test-notifications create \ --action-group ag-critical --notification-type Email \ --email-address admin@contoso.com
Symptoms: CPU exceeded 90% but no alert email received.
Diagnostic checklist:
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Alert rule enabled? |
| 2 | Threshold and aggregation correct (avg vs max)? |
| 3 | Evaluation period and frequency appropriate? |
| 4 | Action group email correct and not in spam? |
| 5 | Alert in fired state but action group failed? |
| 6 | Resource sending metrics (agent installed)? |
# Check alert history az monitor metrics alert list -g rg-monitor -o table # Test action group az monitor action-group test-notifications create \ --action-group ag-critical --notification-type Email \ --email-address admin@contoso.com
NSG Flow — Traffic Allowed in Rules but Blocked
NSG rule allows port 443 but connection fails. IP Flow Verify shows "Denied".
Work through NSG rules, resource state, DNS, and RBAC in order.
# View effective rules (combined NSG on NIC + subnet) az network nic show-effective-nsg -g rg-compute -n vm-nic # Check effective routes az network nic show-effective-route-table -g rg-compute -n vm-nic -o table
Container App Not Scaling
Container App stays at 0 replicas despite HTTP traffic.
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Ingress enabled and external? |
| 2 | KEDA HTTP scaler configured? |
| 3 | minReplicas set to 0 (scale-to-zero enabled)? |
| 4 | Container crashing on startup (check logs)? |
| 5 | Revision active and receiving traffic? |
# Check container app status and logs az containerapp show -g rg-aca -n api-service --query properties.runningStatus az containerapp logs show -g rg-aca -n api-service --follow # Check scaling rules az containerapp show -g rg-aca -n api-service --query properties.template.scale
Symptoms: Container App stays at 0 replicas despite HTTP traffic.
Diagnostic checklist:
| Step | Check |
|---|---|
| ------ | ------- |
| 1 | Ingress enabled and external? |
| 2 | KEDA HTTP scaler configured? |
| 3 | minReplicas set to 0 (scale-to-zero enabled)? |
| 4 | Container crashing on startup (check logs)? |
| 5 | Revision active and receiving traffic? |
# Check container app status and logs az containerapp show -g rg-aca -n api-service --query properties.runningStatus az containerapp logs show -g rg-aca -n api-service --follow # Check scaling rules az containerapp show -g rg-aca -n api-service --query properties.template.scale