Home / Azure

AzureTroubleshootingIntermediate

New Azure VM can't reach the internet - private subnets, default outbound access and the explicit egress fix

VMs in a newly built VNet can't reach the internet, Windows Update or activation. Check whether the subnet is private, add a NAT gateway or other explicit egress, and stop relying on default outbound access.

Deepak Bhardwaj7 min read

Applies toAzure Virtual Network, Azure Virtual Machines and Virtual Machine Scale Sets, Azure NAT Gateway, Azure CLI 2.x

Symptoms

A VM built in a new virtual network has no outbound internet access, while an identical VM in an older VNet works fine. Typical signs:

  • curl or Invoke-WebRequest to public sites times out. DNS resolves fine.
  • Windows activation fails and Windows Update can't reach its endpoints.
  • apt, yum or dnf hang on mirrors. Extensions that download packages fail to provision.
  • Calls to public Microsoft endpoints (Entra ID sign-in, Key Vault without Private Link, container registries) time out.
  • Nothing in the NSG denies the traffic.

The usual cause is that the subnet is private: its defaultOutboundAccess property is false, so Azure no longer gives the VM an implicit outbound public IP. Since the API versions released after 31 March 2026, subnets in new VNets are private by default, and the portal had already made them private by default before that. Existing VNets were not changed. That is why the old VNet works and the new one doesn't.

Quick check: is the subnet private, and does it have explicit egress?

RG=rg-app-prod
VNET=vnet-app-prod

az network vnet subnet list -g $RG --vnet-name $VNET \
  --query "[].{subnet:name, defaultOutbound:defaultOutboundAccess, natGateway:natGateway.id, routeTable:routeTable.id}" \
  -o table

How to read it:

defaultOutbound NAT gateway / route table What the VM gets
False none No internet egress at all. This is your outage.
False NAT gateway attached Egress through the NAT gateway
False route table with 0.0.0.0/0 to a firewall/NVA Egress through the firewall, if the firewall allows it
empty (null) or True none Default outbound access (implicit, Microsoft-owned IP that can change)

A VM can also have explicit egress at NIC level, through an instance public IP or a Standard load balancer with outbound rules. Check both:

VM=vm-app-01
NIC_ID=$(az vm show -g $RG -n $VM --query "networkProfile.networkInterfaces[0].id" -o tsv)

az network nic show --ids $NIC_ID \
  --query "{publicIp:ipConfigurations[0].publicIPAddress.id, lbPools:ipConfigurations[0].loadBalancerBackendAddressPools[].id}" \
  -o json

Prove it from inside the VM without logging in

Run Command works through the VM agent and doesn't need RDP or SSH:

# Linux
az vm run-command invoke -g $RG -n $VM --command-id RunShellScript \
  --scripts "curl -s -m 5 -o /dev/null -w '%{http_code}\n' https://www.microsoft.com || echo FAILED"

# Windows
az vm run-command invoke -g $RG -n $VM --command-id RunPowerShellScript \
  --scripts "Test-NetConnection www.microsoft.com -Port 443 | Select-Object TcpTestSucceeded"

Ping is not a valid test here. Default outbound access IPs never supported ICMP, so ping failing tells you nothing.

Check the effective routes

If the subnet has a route table, look at what the NIC actually uses (the VM must be running):

az network nic show-effective-route-table --ids $NIC_ID -o table

Watch for one trap. User-defined routes with next hop type Internet, often used to send service-tag traffic around the firewall, stop working in a private subnet unless the subnet also has explicit egress. The route still points at Internet, but there is no outbound IP behind it. Service endpoints (VirtualNetworkServiceEndpoint) are not affected.

Symptom → cause → fix

Symptom Likely cause Fix
New VNet, no egress at all, NSG clean Private subnet, no explicit outbound method Attach a NAT gateway to the subnet
Only service-tag bypass routes fail UDR next hop Internet in a private subnet Add a NAT gateway, or send that traffic through the firewall
Egress works but the source IP keeps changing Still on default outbound access Move to a NAT gateway and make the subnet private
Third-party allow-list rejects you Default outbound IP not owned by you NAT gateway with a static public IP or prefix
Flexible VM Scale Set instances have no egress Flexible orchestration never assigns default outbound IPs Explicit egress on the subnet or load balancer
Load balancer backend pool by IP still uses default outbound Known issue documented by Microsoft Attach a NAT gateway to the backend subnet

A NAT gateway is the recommended explicit method for most subnets. It applies to the whole subnet and gives you a static, known source IP.

LOC=westeurope

az network public-ip create -g $RG -n pip-natgw-app --sku Standard \
  --allocation-method Static --location $LOC

az network nat gateway create -g $RG -n natgw-app --location $LOC \
  --public-ip-addresses pip-natgw-app --idle-timeout 4

az network vnet subnet update -g $RG --vnet-name $VNET -n snet-app \
  --nat-gateway natgw-app

Egress through the NAT gateway starts working for running VMs. No restart is needed. Run the Run Command test again to confirm. Check NAT gateway pricing and zone options for your region before you roll it out to every subnet.

Tip

If the subnet already sends 0.0.0.0/0 to Azure Firewall or an NVA, you have explicit egress. Fix the firewall rules (application or network rules for the destinations) rather than adding a NAT gateway to the spoke.

Other explicit options

  • Instance public IP: fine for a single jump box. It doesn't scale and it exposes the VM.
  • Standard load balancer outbound rules: useful when the VMs are already behind a public Standard load balancer.
  • Firewall or NVA via UDR: the usual choice in hub-and-spoke.

Should you flip the subnet back to non-private?

You can set defaultOutboundAccess back to true, but that is a stopgap:

az network vnet subnet update -g $RG --vnet-name $VNET -n snet-app --default-outbound true

Warning

Changing a subnet between private and non-private only takes effect on existing VMs after they are stopped (deallocated) and started. A deallocate means downtime and can change any dynamic public IP. Plan it as a maintenance window. Adding a NAT gateway needs no deallocate, so it is usually the faster fix.

Clearing the "default outbound access" warning on old VNets

The same property explains the portal banner and the Azure Advisor recommendation (Operational Excellence: "Add explicit outbound method to disable default outbound") on VMs in older VNets. To list NICs that still have a default outbound IP:

az graph query -q "
Resources
| where type =~ 'microsoft.network/networkinterfaces'
| where tobool(properties.defaultOutboundConnectivityEnabled) == true
| project nic=name, resourceGroup, subscriptionId, vm=tostring(properties.virtualMachine.id)
" --first 1000 -o table

To clear it safely, in this order:

  1. Add explicit egress to the subnet (NAT gateway or a UDR to a firewall) and test it.
  2. Make the subnet private: az network vnet subnet update ... --default-outbound false.
  3. Deallocate and start each VM in a maintenance window so the NIC drops its default outbound IP.

Caution

Never do step 2 before step 1 on a production subnet. Without explicit egress, VMs lose Windows activation, patching and every public endpoint dependency after their next deallocate, which may be weeks later and hard to trace back to this change.

Prevent it next time

  • Put explicit egress in the network template. In Bicep, set defaultOutboundAccess: false and attach natGateway on the subnet in the same template. In Terraform azurerm, set default_outbound_access_enabled = false and add a NAT gateway association. Pin the property explicitly rather than relying on the API version default, because older API versions and providers still leave it null.
  • Add egress to the VM build checklist. Before handover, run the Run Command HTTPS test and confirm the source IP matches the NAT gateway's public IP.
  • Watch Advisor. Review the default outbound recommendations every month until the count reaches zero.
  • Audit with Resource Graph. Schedule the subnet query across subscriptions to find private subnets with no NAT gateway and no route table. Those are the next outage.
  • Document the egress IPs. Third parties that allow-list your traffic need the NAT gateway public IP or prefix. Default outbound IPs can change without notice.