Introduction

Azure VNet peering connects two virtual networks for private communication. When peering fails or stays disconnected, resources in different VNets cannot communicate, affecting multi-tier applications and cross-region architectures.

Symptoms

Peering creation failed:

```bash $ az network vnet peering create \ --name my-peering \ --resource-group my-rg \ --vnet-name vnet1 \ --remote-vnet /subscriptions/SUB/resourceGroups/other-rg/providers/Microsoft.Network/virtualNetworks/vnet2

"Error: Address space overlap detected between virtual networks" ```

Peering status disconnected:

```bash $ az network vnet peering show \ --name my-peering \ --resource-group my-rg \ --vnet-name vnet1 \ --query '{State:peeringState,Connected:peeringSyncLevel}'

{ "State": "Disconnected", "Connected": "NotSynced" } ```

Connectivity failed:

bash
# Ping from VM in VNet1 to VM in VNet2 fails
# No route to host

Common Causes

  1. 1.Address space overlap - VNets have overlapping IP ranges
  2. 2.Missing reverse peering - Only one direction configured
  3. 3.Subscription access denied - No permission to remote VNet
  4. 4.Different deployment models - Classic vs Resource Manager
  5. 5.NSG blocking traffic - Security rules preventing connectivity
  6. 6.Gateway transit disabled - VPN/ExpressRoute not allowed
  7. 7.Peering in failed state - Previous operation failed

Step-by-Step Fix

Step 1: Check Peering Status

```bash # List all peerings az network vnet peering list \ --resource-group my-rg \ --vnet-name vnet1 \ --query '[].{Name:name,State:peeringState,RemoteVNet:remoteVirtualNetwork.id}'

# Check specific peering az network vnet peering show \ --name my-peering \ --resource-group my-rg \ --vnet-name vnet1 \ --query '{State:peeringState,UseRemoteGateway:allowGatewayTransit,UseHubGateway:useRemoteGateways}' ```

Step 2: Check Address Space Overlap

```bash # Get VNet address spaces az network vnet show \ --name vnet1 \ --resource-group my-rg \ --query 'addressSpace.addressPrefixes'

az network vnet show \ --name vnet2 \ --resource-group other-rg \ --query 'addressSpace.addressPrefixes'

# If overlapping, readdress one VNet # VNet1: 10.0.0.0/16 # VNet2: 10.0.0.0/16 <- OVERLAP

# Fix by changing VNet2 address space az network vnet update \ --name vnet2 \ --resource-group other-rg \ --address-prefixes 10.1.0.0/16 ```

Step 3: Create Bidirectional Peering

```bash # Peering must be created in both directions # VNet1 to VNet2 az network vnet peering create \ --name vnet1-to-vnet2 \ --resource-group my-rg \ --vnet-name vnet1 \ --remote-vnet /subscriptions/SUB/resourceGroups/other-rg/providers/Microsoft.Network/virtualNetworks/vnet2 \ --allow-vnet-access

# VNet2 to VNet1 (required) az network vnet peering create \ --name vnet2-to-vnet1 \ --resource-group other-rg \ --vnet-name vnet2 \ --remote-vnet /subscriptions/SUB/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/vnet1 \ --allow-vnet-access

# Verify both directions az network vnet peering show \ --name vnet1-to-vnet2 \ --resource-group my-rg \ --vnet-name vnet1 \ --query 'peeringState'

az network vnet peering show \ --name vnet2-to-vnet1 \ --resource-group other-rg \ --vnet-name vnet2 \ --query 'peeringState' ```

Step 4: Check Cross-Subscription Permissions

```bash # For cross-subscription peering, need Network Contributor on both VNets az role assignment list \ --scope /subscriptions/SUB1/resourceGroups/my-rg/providers/Microsoft.Network/virtualNetworks/vnet1 \ --query '[].{Role:roleDefinitionName,Principal:principalName}'

az role assignment list \ --scope /subscriptions/SUB2/resourceGroups/other-rg/providers/Microsoft.Network/virtualNetworks/vnet2 \ --query '[].{Role:roleDefinitionName,Principal:principalName}'

# Assign Network Contributor if missing az role assignment create \ --assignee user@example.com \ --role "Network Contributor" \ --scope /subscriptions/SUB2/resourceGroups/other-rg/providers/Microsoft.Network/virtualNetworks/vnet2 ```

Step 5: Check NSG Rules

```bash # Check NSG on source subnet az network nsg show \ --name nsg1 \ --resource-group my-rg \ --query 'securityRules[]'

# Ensure outbound traffic to peered VNet allowed az network nsg rule create \ --nsg-name nsg1 \ --resource-group my-rg \ --name AllowPeeredVNet \ --direction Outbound \ --priority 100 \ --source-address-prefixes 10.0.0.0/16 \ --destination-address-prefixes 10.1.0.0/16 \ --destination-port-ranges '*' \ --protocol '*' \ --access Allow

# Check NSG on destination subnet az network nsg show \ --name nsg2 \ --resource-group other-rg \ --query 'securityRules[]'

# Ensure inbound traffic from peered VNet allowed az network nsg rule create \ --nsg-name nsg2 \ --resource-group other-rg \ --name AllowFromPeeredVNet \ --direction Inbound \ --priority 100 \ --source-address-prefixes 10.0.0.0/16 \ --destination-address-prefixes 10.1.0.0/16 \ --destination-port-ranges '*' \ --protocol '*' \ --access Allow ```

Step 6: Configure Gateway Transit

```bash # If using VPN/ExpressRoute gateway in hub VNet # Enable gateway transit on hub az network vnet peering update \ --name hub-to-spoke \ --resource-group hub-rg \ --vnet-name hub-vnet \ --allow-gateway-transit true

# Use remote gateways on spoke az network vnet peering update \ --name spoke-to-hub \ --resource-group spoke-rg \ --vnet-name spoke-vnet \ --use-remote-gateways true

# Note: Both flags cannot be true on same peering ```

Step 7: Test Connectivity

```bash # Test connectivity between VNets # Create test VMs in each VNet

# From VNet1 VM, test connectivity to VNet2 VM az vm run-command invoke \ --command-id RunShellScript \ --vm-name vm1 \ --resource-group my-rg \ --scripts "ping -c 4 10.1.0.4"

# Check effective routes az network nic show-effective-route-table \ --name vm1-nic \ --resource-group my-rg

# Should show route to peered VNet address space ```

Step 8: Recreate Failed Peering

```bash # If peering stuck in failed state, delete and recreate az network vnet peering delete \ --name my-peering \ --resource-group my-rg \ --vnet-name vnet1

# Wait for deletion to complete az network vnet peering wait \ --name my-peering \ --resource-group my-rg \ --vnet-name vnet1 \ --deleted

# Recreate peering az network vnet peering create \ --name my-peering \ --resource-group my-rg \ --vnet-name vnet1 \ --remote-vnet /subscriptions/SUB/resourceGroups/other-rg/providers/Microsoft.Network/virtualNetworks/vnet2 \ --allow-vnet-access ```

Step 9: Check Global Peering Limits

```bash # Check peering limits az network vnet peering list \ --resource-group my-rg \ --vnet-name vnet1 \ --query 'length(@)'

# Default limit: 500 peerings per VNet # If limit exceeded, request increase or consolidate VNets

# Check if global peering (cross-region) az network vnet show \ --name vnet1 \ --resource-group my-rg \ --query 'location'

az network vnet show \ --name vnet2 \ --resource-group other-rg \ --query 'location' ```

Step 10: Monitor Peering Health

```bash # Create alert for peering state changes az monitor activity-log alert create \ --name vnet-peering-alert \ --resource-group my-rg \ --condition category='ResourceManagement' and operationName='Microsoft.Network/virtualNetworks/virtualNetworkPeerings/write'

VNet Peering States

StateDescriptionAction
InitiatedFirst peering createdCreate reverse peering
ConnectedBoth directions activeNo action needed
DisconnectedOne direction missingRecreate peering
FailedConfiguration errorDelete and recreate

Verification

```bash # After fixing peering az network vnet peering show \ --name vnet1-to-vnet2 \ --resource-group my-rg \ --vnet-name vnet1 \ --query '{State:peeringState,SyncLevel:peeringSyncLevel}'

# Should show: # State: Connected # SyncLevel: FullyInSync

# Test actual connectivity az vm run-command invoke \ --command-id RunShellScript \ --vm-name vm1 \ --resource-group my-rg \ --scripts "curl -I http://10.1.0.4:80"

# Should receive HTTP response from VM in peered VNet ```

Prevention

To prevent Azure VNet peering issues from recurring, implement these proactive measures:

1. Monitor Peering Health

yaml
groups:
- name: azure-networking
  rules:
  - alert: AzureVNetPeeringDisconnected
    expr: |
      azure_vnet_peering_state != 1
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Azure VNet peering is not connected"

2. Use ARM Templates for Consistency

json
{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "resources": [
    {
      "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings",
      "apiVersion": "2021-02-01",
      "name": "[concat(parameters('vnet1Name'), '/peering-to-vnet2')]",
      "properties": {
        "allowVirtualNetworkAccess": true,
        "allowForwardedTraffic": true,
        "allowGatewayTransit": false,
        "useRemoteGateways": false,
        "remoteVirtualNetwork": {
          "id": "[resourceId('Microsoft.Network/virtualNetworks', parameters('vnet2Name'))]"
        }
      }
    }
  ]
}

3. Validate Before Creation

```bash # Pre-flight check script cat << 'EOF' > validate_peering.sh #!/bin/bash VNET1=$1 VNET2=$2 RG=$3

# Check VNets exist az network vnet show --name $VNET1 --resource-group $RG --query id az network vnet show --name $VNET2 --resource-group $RG --query id

# Check no overlapping CIDR CIDR1=$(az network vnet show --name $VNET1 --resource-group $RG --query addressSpace.addressPrefixes[0]) CIDR2=$(az network vnet show --name $VNET2 --resource-group $RG --query addressSpace.addressPrefixes[0]) echo "VNet1: $CIDR1, VNet2: $CIDR2" EOF chmod +x validate_peering.sh ```

Best Practices Checklist

  • [ ] Monitor peering health status
  • [ ] Use ARM templates for consistency
  • [ ] Validate VNets before peering
  • [ ] Document peering relationships
  • [ ] Test connectivity after creation
  • [ ] Set up activity log alerts
  • [Fix Azure Network Security Group Blocking Traffic](/articles/fix-azure-nsg-flow-logs-not-capturing)
  • [Fix Azure Load Balancer Probe Failing](/articles/fix-azure-load-balancer-probe-failing)
  • [Fix Azure Bastion Connection Timeout](/articles/fix-azure-bastion-connection-timeout)
  • [Technical troubleshooting: Fix Azure Aks Pod Crashloopbackoff Issue in Azure](azure-aks-pod-crashloopbackoff)
  • [Technical troubleshooting: Fix Azure Api Management Policy Expression Runtime](azure-api-management-policy-expression-runtime-error)
  • [Technical troubleshooting: Fix Azure App Configuration Feature Flag Not Refre](azure-app-configuration-feature-flag-not-refreshing)
  • [Technical troubleshooting: Fix Azure App Service 503 Always On Disabled Issue](azure-app-service-503-always-on-disabled)
  • [Technical troubleshooting: Fix Azure Application Gateway Err SSL Unrecognized](azure-application-gateway-err-ssl-unrecognized-name-alert)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix Azure VNet Peering Not Connecting", "description": "Troubleshoot Azure VNet peering issues. Check address space overlap, subscription permissions, and peering status.", "url": "https://www.fixwikihub.com/fix-azure-virtual-network-peering-not-connecting", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-03T22:03:38.780Z", "dateModified": "2026-04-03T22:03:38.780Z" } </script>