Fix Azure Virtual Network Setup Issues, Complete Guide

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

Why This Is Happening

You've spun up an Azure Virtual Network, deployed a couple of virtual machines into it, and now nothing talks to anything. VMs can't ping each other. Your app can't reach a storage account. Private endpoints resolve to public IPs even though you did everything the wizard told you. Sound familiar? I've seen this exact pattern dozens of times, and almost every time, it comes down to one of four root causes hiding behind Azure's notoriously unhelpful error messages.

Azure networking fundamentals are deceptively simple on the surface. The portal makes it look like you click a few buttons and you're done. But underneath, you're actually configuring three deeply interconnected systems at once: Azure Virtual Network (the private network fabric), Azure Private Link (the mechanism for routing traffic to Azure services privately), and Azure DNS (the name resolution layer that ties it all together). When any one of these is misconfigured, the symptoms look almost identical, broken connectivity, which is why the error messages never point you in the right direction.

Here's who typically runs into these problems. If you're setting up Azure networking fundamentals for the first time, you've probably created your virtual network and subnets correctly but skipped the DNS configuration step, assuming Azure handles it automatically. (It does, but not for private endpoints.) If you're an admin migrating workloads from on-premises, you're likely hitting address space conflicts or DNS forwarding issues because your on-prem resolver is intercepting Azure-internal queries. And if you're running a multi-subscription environment, you've probably discovered that approving Private Link connections across subscription boundaries doesn't work the way you'd expect from the portal UI.

The four root causes I see most often:

  • Missing or misconfigured Private DNS zones, private endpoints exist, but DNS still resolves to the public IP
  • Network Security Group rules blocking required traffic, NSG deny rules silently drop traffic with no visible error in the VM
  • Overlapping address spaces, a subnet range collides with an on-premises range or another VNet, breaking peering
  • Missing VNet link for Private DNS zones, the Private DNS zone exists but isn't linked to your virtual network, so resolution fails

None of these are bugs. They're configuration gaps, and every one of them is fixable. Let's work through them. Browse all Microsoft fix guides →

The Quick Fix, Try This First

Before going deep, run this diagnostic sequence first. It catches about 60% of Azure virtual network connectivity problems in under five minutes.

Open the Azure portal at portal.azure.com. Navigate to your virtual machine → select Help in the left sidebar → click Connection troubleshoot. This tool runs a real network path analysis between your source VM and any destination (another VM, an IP, a hostname). Set your source VM, enter the destination IP or FQDN, click Check, and wait about 30 seconds.

If it comes back with Reachable but your app still fails, the problem is at the application layer, not the network. Check your application firewall rules and service-level access controls instead.

If it comes back with Unreachable, look at the Next hop field in the result. If next hop shows None, your route table is missing a route, or your NSG has a deny rule intercepting the traffic before it even leaves the subnet. If next hop shows an unexpected IP address, you likely have a User Defined Route (UDR) redirecting traffic somewhere it shouldn't go.

For DNS-specific failures, where your private endpoint is resolving to a public IP, open Azure Cloud Shell (the terminal icon in the top portal nav bar) and run:

nslookup your-resource-name.blob.core.windows.net

If the result shows a public IP (something like 20.60.x.x rather than a 10.x.x.x address in your VNet range), your Private DNS zone either doesn't exist, isn't linked to your VNet, or doesn't have the right A record. That's the fast diagnostic. The sections below walk you through fixing exactly that.

Pro Tip
When you deploy a private endpoint for any Azure service, storage, SQL, Key Vault, Azure automatically creates a Private DNS zone suggestion in the portal. Accept it every single time. If you click past it thinking you'll configure DNS later, you won't remember to come back, and you'll spend an hour debugging what is literally a missing checkbox.
1
Create Your Azure Virtual Network with the Right Address Space

This is where most people make the decision that haunts them later: choosing an address space that conflicts with something else. I know it feels like a small detail, but an overlapping CIDR range will silently break VNet peering and hybrid connectivity in ways that are extremely painful to unravel once VMs are deployed.

In the Azure portal, go to Create a resource → search for Virtual network → click Create. On the Basics tab, set your resource group (use something like test-rg for labs, or your actual resource group name for production), your region, and your VNet name (e.g., vnet-1).

On the IP Addresses tab, this is the critical part. The default address space is 10.0.0.0/16. That works fine in isolation, but if you're connecting to on-premises or other VNets, check your existing ranges first. Use a range from the private address space (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16) and pick something specific enough to avoid collisions.

Add your first subnet, name it subnet-1 and give it a range within your VNet space, like 10.0.0.0/24. Also add the AzureBastionSubnet now (minimum /26), you'll thank yourself in Step 5.

Click Review + createCreate. When deployment completes, you should see your VNet listed under Virtual networks in the portal with your subnets visible under Settings → Subnets. If that blade is empty, the subnet configuration didn't save, go back and add the subnets manually.

2
Configure Network Security Group Rules to Allow Required Traffic

Network Security Groups are Azure's packet filter, and the default rules are more restrictive than most people realize. Out of the box, a new NSG allows all outbound traffic and allows inbound traffic only from within the VNet and from Azure Load Balancer. It denies all other inbound traffic. So if your VMs can't talk to each other across subnets, this is often why, they're not in the same subnet, and no inbound NSG rule allows cross-subnet traffic.

To create an NSG for your subnet: go to Network security groups in the portal → Create. Name it (e.g., nsg-1), assign it to your resource group and region, then click Create.

After it deploys, go to the NSG → Settings → Inbound security rulesAdd. For VM-to-VM connectivity within the VNet:

Source: VirtualNetwork
Source port ranges: *
Destination: VirtualNetwork
Destination port ranges: *
Protocol: Any
Action: Allow
Priority: 100
Name: Allow-VNet-Inbound

For SSH or RDP access from a specific IP range (don't open to the entire internet, I've seen this cause real incidents):

Source: IP Addresses
Source IP: [your admin IP range, e.g. 203.0.113.0/24]
Destination port ranges: 22 (SSH) or 3389 (RDP)
Protocol: TCP
Action: Allow
Priority: 110

Attach the NSG to your subnet: go to your VNet → Subnets → click subnet-1 → set the Network security group field to nsg-1Save. You should see the NSG name appear next to the subnet in the subnet list within 30 seconds. If connectivity is still broken after this, use NSG flow logs (under Monitoring → NSG flow logs), they'll show you exactly which rule is dropping the traffic.

3
Deploy a Private Endpoint for Azure Services

Azure Private Link is what allows your VNet-hosted VMs to talk to Azure PaaS services, Storage, SQL, Key Vault, and others, entirely over Microsoft's private backbone, without any traffic touching the public internet. A private endpoint is the network interface that sits inside your VNet and maps to a specific Azure service instance.

Here's how to deploy one. Navigate to your target Azure service (for example, a Storage account) → go to Security + networking → Networking → Private endpoint connections → click + Private endpoint.

On the Basics tab: name it something descriptive (e.g., pe-storageaccount-vnet1), set the same resource group and region as your VNet.

On the Resource tab: select Connect to an Azure resource in my directory, choose your resource type (e.g., Microsoft.Storage/storageAccounts), select the specific resource, and pick the target sub-resource (e.g., blob).

On the Virtual Network tab: select vnet-1 and subnet-1. This is where the private endpoint NIC lands inside your network.

On the DNS tab, this is the step people skip. Set Integrate with private DNS zone to Yes. Azure will create the appropriate Private DNS zone (e.g., privatelink.blob.core.windows.net) and automatically add an A record pointing your storage account's hostname to the private IP. Click Review + createCreate.

After deployment, the private endpoint connection state should show Approved. If it shows Pending, someone needs to approve it, either you (if it's your own subscription) or the resource owner (in cross-subscription scenarios).

4
Link Your Private DNS Zone to the Virtual Network

This step fixes the single most common Azure DNS resolution failure I see: the private endpoint exists, the Private DNS zone exists, but DNS still returns the public IP. The reason is almost always that the Private DNS zone isn't linked to the VNet. Without the link, VMs in that VNet don't use the private zone for lookups, they fall through to Azure's public DNS, which returns the public IP.

Go to Private DNS zones in the portal. Find your zone, for a blob storage private endpoint, it will be named privatelink.blob.core.windows.net. Click on it → go to Settings → Virtual network links+ Add.

Set the Link name to something identifiable (e.g., link-vnet1), select your subscription, then select vnet-1 as the virtual network. Leave Enable auto registration off unless you want all VMs in the VNet to auto-register their hostnames in this zone (you usually don't want that for a privatelink zone). Click OK.

Once the link shows status Completed, test from a VM inside the VNet. Open the Azure Bastion session to one of your VMs and run:

nslookup yourstorageaccount.blob.core.windows.net
# Expected result:
# Name: yourstorageaccount.privatelink.blob.core.windows.net
# Address: 10.0.0.5  <-- private IP from your subnet

If you still see a public IP after the link is in place, check that the A record actually exists in the zone: go to the Private DNS zone → Overview and look for your storage account hostname under the record sets list. If the A record is missing, add it manually: type A, name matching your storage account name, TTL 3600, IP matching the private endpoint's NIC private IP (visible under the private endpoint → Network interface).

5
Validate VM Connectivity Using Azure Bastion

Once networking is configured, you need to actually validate it from inside the VNet, not from your laptop, which sits outside and may have a completely different network path. Azure Bastion is purpose-built for this: it gives you browser-based RDP and SSH access to your VMs directly through the Azure portal over TLS, without needing a public IP on the VM or an open RDP/SSH port to the internet.

If you added the AzureBastionSubnet during VNet creation in Step 1, deploying Bastion is straightforward. Go to Bastions in the portal → Create. Name it (e.g., bastion), select your resource group, region, and vnet-1. Azure will auto-select the AzureBastionSubnet. You'll also need a public IP for Bastion itself, create a new Standard SKU public IP. Click Review + createCreate. Deployment takes 5–10 minutes.

Once deployed, navigate to vm-1 → click Connect → select Bastion → enter your VM credentials → Connect. A browser tab opens with a full terminal or RDP session inside the VM.

From inside vm-1, test connectivity to vm-2:

# Linux
ping 10.0.0.5   # vm-2's private IP
curl -I https://yourstorageaccount.blob.core.windows.net

# Windows PowerShell
Test-NetConnection -ComputerName 10.0.0.5 -Port 22
Resolve-DnsName yourstorageaccount.blob.core.windows.net

If ping fails but Test-NetConnection on a specific port succeeds, your NSG is likely blocking ICMP (ping) while allowing TCP, that's a common and acceptable configuration. The TCP test is more meaningful. If Resolve-DnsName returns a private IP from your subnet range, your DNS configuration is working correctly end-to-end.

Advanced Troubleshooting

When the basics are set up but things still aren't working, these are the deeper areas I check, particularly in enterprise and domain-joined environments.

Cross-Subscription Private Link Approval

If your private endpoint connects to a resource in a different Azure subscription, the connection state will show Pending until the resource owner approves it. This doesn't happen automatically, even between subscriptions in the same Azure AD tenant. The resource owner needs to go to their resource → Networking → Private endpoint connections → select the pending connection → click Approve. You can also approve via Azure CLI:

az network private-endpoint-connection approve \
  --resource-group <resource-group> \
  --name <connection-name> \
  --resource-name <resource-name> \
  --type Microsoft.Storage/storageAccounts \
  --description "Approved for VNet integration"

On-Premises DNS Forwarding Conflicts

In hybrid environments where your on-premises DNS resolver handles name resolution, Azure Private DNS zones don't get queried because your DNS requests never reach Azure's resolver at 168.63.129.16. The fix is to configure conditional forwarders on your on-premises DNS server for each privatelink.* zone, pointing to the Azure DNS Private Resolver or to 168.63.129.16 directly. For example, in Windows Server DNS Manager, add a conditional forwarder for privatelink.blob.core.windows.net pointing to 168.63.129.16.

Network Watcher for Flow Analysis

Enable Azure Network Watcher (it's free per region) and turn on NSG flow logs on your NSG. Flow logs write to a storage account and show every allowed and denied connection attempt with source IP, destination IP, port, and the rule that matched. This is far more useful than guessing. Go to Network Watcher → NSG flow logs → + Create, select your NSG, pick a storage account, and set the retention period. Within a few minutes of enabling, you'll see real traffic data.

VNet Peering and Route Tables

If you're peering two VNets and traffic isn't flowing between them, check both sides of the peering. VNet peering is not transitive by default, if VNet A peers to VNet B, and VNet B peers to VNet C, VNet A cannot reach VNet C without additional configuration (like a Network Virtual Appliance or Azure Route Server). Also verify that both peerings show status Connected, a peering in Disconnected or Initiated state means the other side hasn't accepted yet.

When to Call Microsoft Support
If you've confirmed your NSG rules, Private DNS zones, VNet links, and peering configurations are all correct, and connectivity still fails, you may be hitting a platform-level issue or a quota limit. At that point, open a support ticket at Microsoft Support. Include your VNet resource IDs, the source and destination IPs you're testing, Network Watcher flow log excerpts, and the exact nslookup or Test-NetConnection output you're seeing. The more specific your evidence, the faster the support engineer can help.

Prevention & Best Practices

Getting Azure networking fundamentals right the first time saves hours of troubleshooting. The biggest thing I tell teams new to Azure networking: plan your IP address space before you create anything. Once VMs are deployed into a subnet, you can't resize that subnet without deleting and redeploying the resources in it. That's not a theoretical problem, it's a real operational nightmare when it happens in production.

Use a documented IP allocation plan. Write down which CIDR blocks are assigned to which VNets, subnets, and on-premises ranges. Azure has no automatic mechanism to detect conflicts across your entire organization, that responsibility is yours. Tools like Azure Virtual Network Manager help with governance at scale, but even a shared spreadsheet beats nothing.

Always use Azure Resource Manager (ARM) templates, Bicep, or Terraform for network infrastructure, not the portal click-through. Portal deployments are difficult to reproduce, audit, and version-control. Infrastructure-as-code lets you catch configuration drift, review changes in pull requests, and redeploy identical environments in different regions or subscriptions.

For production environments, always enable diagnostic settings on your NSGs, VNets, and Private endpoints. Route logs to a Log Analytics workspace. The Azure Monitor query language (KQL) makes it straightforward to build alerts for unexpected traffic patterns or denied connections.

Tag every network resource with at minimum: environment (prod/dev/staging), owner team, and cost center. Azure networking resources multiply fast, without tags, it becomes impossible to track what belongs to what project or who to contact when something breaks at 2am.

Quick Wins
  • Always create the AzureBastionSubnet (/26 minimum) during initial VNet setup, retrofitting it later requires subnet space you may not have
  • Enable Private DNS zone integration at the time you create private endpoints, not as an afterthought, the portal makes it a one-click step that saves you 30 minutes of manual DNS configuration
  • Use Network Watcher → Connection Monitor to set up continuous end-to-end connectivity checks between your critical VM pairs, it alerts you when paths break before your users notice
  • Document your NSG rules with meaningful names and descriptions, Allow-SQL-from-AppSubnet is infinitely more useful than Port1433-rule when you're debugging at midnight

Frequently Asked Questions

What is IP address 168.63.129.16 in Azure and why does it keep showing up?

This is Azure's internal virtual public IP address, and it's one of the most commonly Googled questions from people new to Azure networking fundamentals. It's not a real external IP, it's a virtual address used by the Azure platform to enable communication between your VMs and Azure infrastructure services. Specifically, 168.63.129.16 is the address your VMs use to reach Azure DNS, to communicate with the Azure host agent (DHCP, health monitoring), and to receive WireServer responses for the VM extension pipeline. If you block this IP in your NSG or firewall, your VMs will start losing DNS resolution and potentially fail health checks. Never block it.

Why is my Azure Virtual Network FAQ page showing my private endpoint still resolving to a public IP?

This is almost always because the Private DNS zone isn't linked to your VNet, or the A record inside the zone is missing. Open your Private DNS zone in the portal and check two things: first, under Virtual network links, confirm your VNet is listed with status Completed. Second, under Overview, confirm there's an A record matching your resource's hostname pointing to a private IP in your VNet range (e.g., 10.x.x.x). If either of those is missing, add it. After fixing, you may need to wait a minute for DNS cache to clear, or run ipconfig /flushdns on Windows or sudo systemd-resolve --flush-caches on Linux inside the VM.

What is Azure Bastion and do I actually need it if I already have a VPN?

Azure Bastion is a fully managed PaaS service that gives you browser-based RDP and SSH access to your VMs directly through the Azure portal, without needing a public IP on the VM or open RDP/SSH ports to the internet. Even if you have a VPN, Bastion is worth having because it works when your VPN is down, it doesn't require client software, and it provides audit logs of every session. It's also the only reliable way to access a VM that has lost network connectivity due to a misconfigured NSG, because Bastion connects to the VM through the Azure management plane, bypassing your data plane NSG rules. For lab environments, the Basic SKU is low cost. For production, use the Standard SKU for features like IP-based connection and shareable links.

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

When your private endpoint is in a different subscription than the target resource, the connection approval doesn't happen automatically, you need explicit action from the resource owner. The resource owner goes to their resource in the portal → Networking → Private endpoint connections → finds the connection in Pending state → clicks Approve and optionally adds a description. Alternatively, you can do this entirely through the Azure CLI with az network private-endpoint-connection approve or via PowerShell with Approve-AzPrivateEndpointConnection. Both approaches require the approver to have at least the Contributor role on the target resource. Once approved, the connection state changes to Approved and traffic starts flowing through the private endpoint immediately.

My two Azure VMs are in the same VNet but can't reach each other, what's wrong?

If both VMs are in the same VNet, Azure's default routing should allow traffic between them without any extra configuration. The most common culprit when this fails is a Network Security Group deny rule, either on the subnet or on the VM's NIC directly. Check both the subnet-level NSG and the NIC-level NSG for deny rules that might be matching before your allow rules (lower priority number wins). Also check that the OS-level firewall (Windows Firewall or iptables/ufw on Linux) isn't blocking the traffic, this is a layer above NSGs and Azure has no visibility into it. Use Network Watcher → Connection troubleshoot to diagnose at the Azure layer, and if that shows the path is clear, the issue is inside the OS.

What's the difference between Azure NAT Gateway, Route Server, and Traffic Manager, when do I use each?

These three services solve completely different problems and are not interchangeable. NAT Gateway gives your VNet a stable, predictable outbound public IP for internet-bound traffic, use it when you need consistent SNAT behavior and don't want to rely on Azure's default outbound internet access (which Microsoft has been deprecating for new deployments). Route Server is for BGP route exchange between your VNet and Network Virtual Appliances (NVAs) or ExpressRoute/VPN gateways, it's an enterprise tool for complex hybrid routing scenarios. Traffic Manager is a global DNS-based load balancer that routes end-user requests to the geographically closest or healthiest endpoint across multiple Azure regions, use it for multi-region failover and global load distribution. If you're just getting started with Azure networking fundamentals, you'll encounter NAT Gateway first; Route Server and Traffic Manager come into play as your architecture grows.

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.