Fix Azure Virtual Network: Setup, Errors & Best Practices

Microsoft Fix Intermediate 14 min read Official Docs Grounded Updated April 20, 2026

Why This Is Happening

You've spun up a couple of Azure VMs. They sit in the same resource group. You'd expect them to just talk to each other , but they can't. Or maybe you've got a web app that should be hitting an Azure SQL database over a private connection, and instead traffic is going out over the public internet. Or the DNS resolution inside your virtual network is completely broken, and your services can't find each other by name at all.

I've seen all three of these situations cause real production outages, and in every case the root cause was a misunderstood Azure Virtual Network (VNet) concept. Azure's networking model is not the same as on-premises networking, and it's not the same as AWS VPCs either. It has its own rules, its own defaults, and its own failure modes, and Microsoft's error messages in this space range from "vague" to "actively misleading."

The three most common categories of Azure Virtual Network problems I see are:

  • Isolation misconfiguration: subnets that aren't properly segmented, address spaces that overlap when you try to peer two VNets, or Network Security Group (NSG) rules that silently block traffic without surfacing a clear error message to the user.
  • Private connectivity failures: Azure Private Link and Private Endpoints are genuinely powerful, but the setup requires you to get DNS right at the same time as you get the networking right. Miss either one and your app just sees a timeout.
  • DNS resolution breakdown: Azure provides its own internal DNS through Azure DNS, but as soon as you introduce custom DNS servers, private DNS zones, or a hybrid on-premises connection, resolution can fall apart in ways that are hard to diagnose.

The frustrating thing is that when any of these breaks, Azure will often still show your resource as "Running" or "Healthy" in the portal. The control plane is fine. It's the data plane that's silently failing. So you're staring at green checkmarks while your application times out.

This guide walks through every layer: creating a properly isolated Azure Virtual Network, locking it down with NSG rules, wiring up Private Link for private service access, and getting DNS to actually resolve correctly. Every step is grounded in Microsoft's official documentation.

Browse all Microsoft fix guides →

The Quick Fix, Try This First

If your Azure VMs in the same virtual network suddenly can't communicate, the single most common culprit is an NSG rule that was added and forgotten. Before you go deep on network topology, do this first.

Go to the Azure portal. Navigate to your VM's Networking blade, it's in the left sidebar of the VM resource. You'll see "Inbound port rules" and "Outbound port rules." Look for any Deny rule with a priority number lower than your Allow rules. NSG rules are processed lowest-number-first, so a Deny rule at priority 100 beats an Allow rule at priority 200 every single time.

If you see a broad DenyAllInBound rule (priority 65500, this one is the Azure default and is fine), but also see a custom Deny rule at a lower priority covering your traffic, that's your problem. Either delete the Deny rule or add an Allow rule with a lower priority number.

For a quick connectivity test between two VMs, use the Network Watcher tool in the portal. Search "Network Watcher" in the top bar, select Connection troubleshoot, pick your source VM, enter the destination IP (or VM name), specify the port, and hit Check. It will tell you exactly which NSG rule or User Defined Route (UDR) is blocking the packet. This tool has saved me hours, use it before you try anything else.

If you're seeing DNS failures rather than connectivity failures: open a terminal on your VM and run:

nslookup <your-resource-hostname> 168.63.129.16

That IP address (168.63.129.16) is Azure's internal DNS resolver, it's a virtual public IP owned by Microsoft and it's always reachable from within any Azure VNet. If resolution works against that IP but not your configured DNS server, your custom DNS server is the problem, not the VNet.

Pro Tip
When you create a new VNet in the Azure portal, the default DNS setting points to Azure-provided DNS (168.63.129.16 under the hood). The moment you add a custom DNS server under VNet → DNS servers, you take full responsibility for resolution, including forwarding Azure internal hostnames. If you add a custom DNS server and don't configure it to forward *.internal.cloudapp.net and privatelink.* zones back to 168.63.129.16, your Private Endpoints will silently break.
1
Create and Configure Your Azure Virtual Network

Start in the Azure portal (portal.azure.com). In the search bar at the top, type Virtual networks and select it from the list. Click + Create in the top-left.

On the Basics tab, set your subscription, resource group (test-rg is fine for learning), name your VNet (vnet-1 following Microsoft's naming convention), and choose your region. Pick the region closest to your workloads, East US 2 is a solid default. Click Next: IP Addresses.

This is where most beginners make a mistake that bites them later. The default address space Azure suggests is 10.0.0.0/16. That gives you 65,536 IP addresses. It sounds like plenty, and it is, but if you ever try to peer this VNet with another VNet, the address spaces cannot overlap. Plan your IP space upfront. If you have multiple VNets (dev, staging, prod), give them non-overlapping ranges: 10.0.0.0/16, 10.1.0.0/16, 10.2.0.0/16.

Add a subnet named subnet-1 with the range 10.0.0.0/24. Azure reserves the first four IPs and the last IP in every subnet, so a /24 gives you 251 usable addresses, more than enough to start. Click Review + create, then Create.

Once deployment completes (usually under 30 seconds), open the new VNet resource and verify the Address space and Subnets show exactly what you configured. If they don't match, don't proceed, delete and recreate. Address space mismatches are extremely painful to fix after VMs are deployed into the network.

2
Attach a Network Security Group to Lock Down Traffic

A VNet without an NSG is wide open by default, resources in the same VNet can talk to each other freely, and outbound internet access is allowed. That's fine for a sandbox, but in any real deployment you need explicit rules.

Search for Network security groups in the portal and click + Create. Name it nsg-1, put it in the same resource group and region as your VNet, then hit Create.

Once created, open the NSG and go to Inbound security rules in the left sidebar. You'll see three default rules Azure puts in automatically:

  • AllowVnetInBound (priority 65000), allows all traffic from within the VNet address space
  • AllowAzureLoadBalancerInBound (priority 65001), allows Azure health probes
  • DenyAllInBound (priority 65500), blocks everything else from the internet

To allow RDP access to a Windows VM only from your IP, click + Add. Set Source to IP Addresses, enter your public IP in the Source IP ranges field, set Destination port ranges to 3389, Protocol to TCP, Action to Allow, and Priority to something low like 100. For SSH on Linux VMs, do the same but with port 22.

Now associate the NSG with your subnet. Go to the NSG → Subnets in the left menu → + Associate. Select your VNet and subnet. You can also associate an NSG directly with a VM's network interface card (NIC) for more granular control, just know that both subnet-level and NIC-level NSGs are evaluated, and both must allow the traffic for a packet to get through.

After associating, use Network Watcher → IP flow verify to confirm your rules are behaving as expected before you deploy anything into the subnet.

3
Deploy VMs and Verify Internal Connectivity

With the VNet and NSG ready, deploy two virtual machines into subnet-1. During VM creation, on the Networking tab, make sure the Virtual network dropdown shows vnet-1 and the Subnet shows subnet-1. Set Public IP to None if you're going to use Azure Bastion for access (which is the right call, exposing RDP/SSH directly to the internet is a bad habit).

While still in the Networking tab of VM creation, confirm the NSG is set to Advanced and points to nsg-1. Do this for both vm-1 and vm-2.

Once both VMs are running, deploy an Azure Bastion host to get console access. Search Bastions in the portal → + Create. Bastion requires its own dedicated subnet named exactly AzureBastionSubnet (the name is mandatory, no exceptions). Add this subnet to your VNet under VNet → Subnets → + Subnet. Give it a /26 or larger, 10.0.1.0/26 works well. Then create the Bastion resource pointing at that subnet.

After Bastion deploys, open vm-1 in the portal, click ConnectBastion, enter the VM credentials, and you'll get a browser-based RDP or SSH session. From inside vm-1, ping vm-2's private IP address (find it under vm-2 → Networking → Network Interface → IP configurations). A successful ping confirms your VNet, NSG, and subnet routing are all working correctly.

If the ping fails, check NSG rules first (the AllowVnetInBound default should allow ICMP within the VNet). If that rule is intact, check that both VMs are in the same VNet and subnet, cross-subnet traffic within the same VNet is still allowed by the default rules.

4
Configure Azure Private Link and Private Endpoints

Once your basic VNet is working, the next step most teams need is Private Link, the mechanism for accessing Azure PaaS services (like Azure Storage, SQL Database, Key Vault) over your private network instead of the public internet.

The concept: you create a Private Endpoint in your VNet. That endpoint gets a private IP address from your subnet. Azure then routes all traffic destined for that PaaS service through that private IP, it never leaves your VNet. The public endpoint on the service can optionally be disabled entirely.

To create a Private Endpoint for an Azure Storage account: open your storage account → Security + networkingPrivate endpoint connections+ Private endpoint. On the Resource tab, select blob as the target sub-resource. On the Virtual Network tab, select vnet-1 and subnet-1. On the DNS tab, this is critical, leave Integrate with private DNS zone set to Yes. This creates a private DNS zone named privatelink.blob.core.windows.net and links it to your VNet automatically.

After creation, test from a VM inside the VNet:

nslookup <your-storage-account>.blob.core.windows.net

You should see it resolve to a 10.x.x.x private IP, not a public Azure IP starting with 52. or 40.. If you see a public IP, the private DNS zone integration didn't attach correctly. Go to your VNet → DNS servers and make sure it's set to Default (Azure-provided), or if you have a custom DNS, that it's forwarding privatelink.blob.core.windows.net to 168.63.129.16.

To approve Private Link connections across subscriptions, something that comes up in hub-and-spoke enterprise setups, go to the service provider resource → Private endpoint connections, find the pending connection, and click Approve. You can also do this via Azure CLI:

az network private-endpoint-connection approve \
  --name <connection-name> \
  --resource-group <resource-group> \
  --resource-name <service-name> \
  --type Microsoft.Storage/storageAccounts
5
Validate and Configure Azure DNS for Private Zones

DNS is where Azure networking quietly breaks most often. The architecture is elegant, but it requires every piece to be wired together correctly.

Azure DNS private zones work on the concept of virtual network links. A private DNS zone by itself does nothing, it only becomes active for a VNet when you create a link between them. Go to your private DNS zone → Virtual network links+ Add. Select your VNet. Enable Auto registration if you want VMs in this VNet to automatically register their hostnames in this zone (useful for internal service discovery).

Common DNS scenarios from the official documentation to cover:

  • Azure-only workloads: Use Azure-provided DNS (the default). Private DNS zones handle name resolution for Private Endpoints automatically when you use the portal's "integrate with private DNS zone" option.
  • Hybrid on-premises + Azure: Deploy an Azure DNS Private Resolver in your VNet. Configure a forwarding ruleset that sends Azure-internal queries to 168.63.129.16 and everything else to your on-premises DNS. This avoids the old pattern of deploying custom DNS VMs, which adds operational overhead.

To validate that a private DNS zone is resolving correctly within a VNet, run this from a VM inside the VNet:

# Resolve a hostname in a private zone
Resolve-DnsName -Name "vm-1.internal.cloudapp.net" -Server 168.63.129.16

# Check private endpoint DNS resolution
Resolve-DnsName -Name "mystorageaccount.blob.core.windows.net"

If the second command returns a public IP instead of a private one, the private DNS zone link is either missing or the zone name doesn't exactly match the required privatelink.* format. Zone name typos are a surprisingly common cause of Private Endpoint DNS failures, privatelink.blob.core.windows.net must be exact, including the privatelink prefix.

One more thing: when you connect two VNets via VNet peering, DNS private zones are not automatically shared. You must create a separate virtual network link for each peered VNet that needs to resolve names in that zone. Missing this step is the #1 reason DNS works in one VNet but breaks in a peered VNet.

Advanced Troubleshooting

When the basics don't resolve your Azure Virtual Network issue, you need to go deeper. Here are the diagnostic paths I reach for on complex cases.

Azure Network Watcher, Your Best Diagnostic Tool

Network Watcher is underused and it's excellent. Enable it per region: search Network Watcher in the portal → Overview → select your subscription and region → click Enable network watcher. Then use:

  • IP flow verify: Tests whether a specific packet (source IP, destination IP, port, protocol) would be allowed or denied by NSG rules on a given NIC. Gives you the exact rule name that's making the decision.
  • Next hop: Shows you what Azure's routing table says is the next hop for a packet from a given VM to a given destination IP. If User Defined Routes (UDRs) are misconfigured, you'll catch it here.
  • Connection troubleshoot: Performs an end-to-end connectivity test between two resources, including latency measurement. Works across VNet peerings and even through Network Virtual Appliances (NVAs).
  • NSG flow logs: Enable these on your NSGs and ship them to a storage account or Log Analytics. They record every allowed and denied flow. Indispensable for figuring out why an intermittent connection is dropping.

VNet Peering Failures

If two VNets can't communicate after peering, check these in order:

  1. Peering status on both sides should show Connected, a status of Initiated on one side means the other VNet hasn't had peering configured yet. Peering is not bidirectional automatically.
  2. Address spaces must not overlap. If they do, the peering will show Disconnected and there's no fix short of re-IP-ing one VNet.
  3. Check whether Allow forwarded traffic and Allow gateway transit are configured correctly for your hub-and-spoke topology.

Private Endpoint Connectivity Errors

The official Microsoft troubleshooting steps for Private Endpoint connectivity problems focus on three areas: DNS resolution (covered above), NSG rules on the Private Endpoint subnet, and network policy settings. By default, NSG rules and UDRs are not enforced on Private Endpoint network interfaces, you have to explicitly enable Private endpoint network policies on the subnet if you want NSG rules to apply to Private Endpoint traffic. Go to the subnet → Edit → set Private endpoint network policy to Enabled.

Route Table (UDR) Conflicts

If you have a Network Virtual Appliance (NVA) like Azure Firewall in a hub VNet, and you've attached a route table to your spoke subnet that forces all traffic through the NVA (0.0.0.0/0 pointing to the NVA's private IP), that route will also intercept Private Endpoint traffic unless you add a more specific route for the private endpoint IP that bypasses the NVA. Azure Firewall needs explicit application rules to allow the traffic or it will silently drop it.

When to Call Microsoft Support
If you've verified NSG rules, DNS resolution, peering status, and route tables, and traffic is still failing, the issue may be a platform-level bug or a quota/limit that's silently blocking resource creation. At that point, open a support ticket at Microsoft Support. Before you do, run Network Watcher → Connection troubleshoot and save the output, it dramatically speeds up the support process. Also collect the Correlation ID from any failed portal operations (it appears in the notification bell).

Prevention & Best Practices

Most Azure Virtual Network problems are preventable. The issues I see repeatedly in enterprise environments almost always trace back to shortcuts taken during initial setup that compound over time.

The single best thing you can do is plan your IP address space before deploying anything. Write it down. A typical hub-and-spoke design might look like: Hub VNet at 10.0.0.0/16, Dev spoke at 10.1.0.0/16, Staging at 10.2.0.0/16, Production at 10.3.0.0/16. Reserve address ranges for future VNets now. Changing VNet address spaces after VMs are deployed is painful, you have to either redeploy everything or use some creative subnet manipulation that the portal doesn't always support cleanly.

Use Azure Policy to enforce networking standards at scale. For example, you can write a policy that requires every subnet to have an NSG associated, and that blocks creation of Public IPs for VMs in certain resource groups. The Azure Well-Architected Framework networking guidelines recommend this as a core control. It's far easier to enforce compliance with a policy than to audit manually after the fact.

For DNS in hybrid environments, the Azure DNS Private Resolver (covered in official docs as a recommended pattern) is the right architecture. It replaces the old pattern of running Windows Server DNS VMs for hybrid resolution. The Private Resolver is fully managed, highly available by design, and integrates natively with private DNS zones and conditional forwarders. The architecture patterns for hub-and-spoke networks specifically reference the DNS Private Resolver as the recommended design.

Tag every networking resource consistently. Use tags like environment: production, team: platform, cost-center: IT. VNet peerings, NSGs, route tables, and Private Endpoints multiplied across subscriptions become unmanageable fast without good tagging. Azure Cost Management and Azure Policy both rely on tags to work effectively.

Quick Wins
  • Enable NSG flow logs on every NSG and retain them for at least 30 days, you'll thank yourself the next time there's a connectivity incident at 2am.
  • Use the Azure VNet FAQ and Private Link FAQ in the official docs as a checklist before raising a support ticket, they cover the top 20 failure modes very thoroughly.
  • Always associate NSGs at the subnet level (not just NIC level), it's easier to reason about and audit, and it prevents VMs from being deployed into unprotected subnets.
  • Test Private Endpoint DNS resolution from inside the VNet immediately after creation, don't wait until your application fails to discover that the DNS zone link is missing.

Frequently Asked Questions

What is the IP address 168.63.129.16 and why does Azure use it?

168.63.129.16 is a virtual public IP address owned and operated by Microsoft. It acts as the communication channel between Azure's host agent and virtual machines, and also serves as Azure's internal DNS resolver for VMs. Even though it looks like a public IP, it's only reachable from within Azure infrastructure, you can't reach it from the internet and nothing outside Azure can spoof it. If you're running custom firewall rules inside a VM (like Windows Firewall or iptables), make sure you're not blocking outbound traffic to this IP, because that will break DNS resolution, VM agent heartbeats, and health monitoring. The official Azure docs specifically call out this IP as something to whitelist if you're running restrictive outbound rules inside your VMs.

How do I fix Azure Private Endpoint connectivity problems when DNS resolves correctly but connections still time out?

When DNS resolves to the correct private IP but connections still time out, the issue is almost always a network policy or NSG rule on the Private Endpoint's subnet. First, check whether Private endpoint network policies are enabled on the subnet, if they are, verify that your NSG rules explicitly allow traffic from your source VM to the private endpoint's IP on the required port. Second, check for User Defined Routes on the subnet that might be forcing traffic through a firewall or NVA that isn't configured to allow the connection. Use Network Watcher's Connection troubleshoot tool, which will trace the packet path and show you exactly where it's being dropped. The Azure Private Endpoint troubleshooting guide in the official docs walks through each failure scenario with specific diagnostic commands.

Why can't my two Azure VMs communicate even though they're in the same virtual network?

The most common cause is a custom Deny rule in a Network Security Group that's overriding the default AllowVnetInBound rule. Remember that NSG rules are evaluated by priority number, lower numbers win. A Deny rule at priority 200 beats an Allow rule at priority 300. Open the VM's Networking blade in the portal and look at the "Effective security rules" link, this shows you the combined result of both the subnet-level NSG and the NIC-level NSG in priority order, which makes it immediately obvious which rule is blocking the traffic. If NSGs look fine, check that both VMs actually have IPs in the same VNet address space, it's easy to accidentally deploy a VM into the wrong VNet if you have several in the same region.

How do I approve Azure Private Link connections across different subscriptions?

When a consumer in Subscription A creates a Private Endpoint that targets a Private Link service or PaaS resource in Subscription B, the connection starts in a "Pending" state until the resource owner in Subscription B approves it. To approve it, go to the service resource in Subscription B → Private endpoint connections → find the pending request → click Approve. You can also use the Azure CLI command az network private-endpoint-connection approve with the appropriate parameters if you need to automate this as part of a deployment pipeline. If you need auto-approval without manual intervention, configure the Private Link service to use auto-approval for specific subscription IDs, this is under the Private Link service resource's Auto-approve settings.

What are the Azure Virtual Network address space limits and can I add more address space later?

A single Azure Virtual Network supports up to 65,536 IP addresses with a /16 prefix, that's the largest single address space allowed. You can assign multiple address spaces (CIDR blocks) to a single VNet though, so if you run out of room you can add a non-overlapping address space without recreating the VNet. Go to your VNet → Address space → Add a new CIDR block. The limitation is that you cannot add an address space that overlaps with any VNet you've already peered with. Also worth knowing: subnets within a VNet can be resized, but only if the new range still falls within the VNet's address space and doesn't conflict with other subnets. Azure reserves 5 IPs per subnet (first four and last one), so plan accordingly when sizing subnets.

How does Azure DNS work for private DNS zones, do I need to do anything to make it work?

Azure private DNS zones don't work automatically, they require a virtual network link to each VNet that should be able to resolve names in that zone. Creating the zone alone does nothing. After creating the zone, go to the zone resource → Virtual network links → Add link → select your VNet. Enable auto-registration if you want VMs to automatically register A records. For Private Endpoints, the Azure portal handles zone creation and linking for you if you check "Integrate with private DNS zone" during Private Endpoint creation, but if you're deploying via Terraform or ARM templates, you have to create both the zone and the virtual network link explicitly. One thing that catches people out in hub-and-spoke topologies: the DNS zone only resolves for VNets that have a link to it, so every spoke VNet needs its own link to the shared private DNS zones hosted in the hub.

Related Microsoft Fix Guides

H
Sai Kiran Pandrala
Our team includes certified Microsoft engineers, Azure architects, and system administrators with 10+ years of enterprise IT experience. Every guide is written from hands-on troubleshooting, not guesswork. We test every fix before publishing.