---
cuppy_hub: azure
cuppy_path: reference/networking/nsgs-and-routes.md
cuppy_section: docs
cuppy_doc: ATTG-WT7B
cuppy_doc_uuid: 0a2d73e2-1832-4860-9d5f-9661c09bba2b
cuppy_permalink: https://cuppy.io/azure/d/ATTG-WT7B
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/networking/nsgs-and-routes
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 41cbafdc997e6713ec5c132384c3dc6dc77f7b1a1e030bc3f41a24a7cbb223cb
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# NSGs and routes

## Network security group rules

- **Priority 100–4096**, lowest number first; the first matching rule decides and processing stops. Rules match on the five-tuple (source, source port, destination, destination port, protocol). Two rules can't share a priority and direction. NSGs are stateful: return traffic of an allowed flow is allowed.
- **Order:** inbound, the **subnet's NSG first, then the NIC's**; outbound, NIC then subnet. Traffic must be allowed by both when both exist. A subnet or NIC with no NSG allows everything at that level.
- **Sources and destinations:** IPs, CIDRs, **service tags** (`VirtualNetwork`, `AzureLoadBalancer`, `Internet`, `Storage.WestEurope`, `AzureCloud`, …) or **application security groups**. NICs in one ASG must be in the same VNet, and an ASG-to-ASG rule needs both in the same VNet.
- Azure Virtual Network Manager **security admin rules** are evaluated before NSG rules.

**Default rules** (can't be deleted; override them with lower numbers):

| Direction | Priority | Rule | Effect |
|---|---|---|---|
| Inbound | 65000 | AllowVnetInBound | `VirtualNetwork` → `VirtualNetwork`, allow (includes peered VNets and connected on-premises ranges) |
| Inbound | 65001 | AllowAzureLoadBalancerInBound | `AzureLoadBalancer` → any, allow (health probes) |
| Inbound | 65500 | DenyAllInBound | Deny |
| Outbound | 65000 | AllowVnetOutBound | `VirtualNetwork` → `VirtualNetwork`, allow |
| Outbound | 65001 | AllowInternetOutBound | Any → `Internet`, allow |
| Outbound | 65500 | DenyAllOutBound | Deny |

Things NSGs don't filter, or treat specially:

- **168.63.129.16 and 169.254.169.254** (host DHCP, DNS, IMDS, health) are platform addresses; blocking 168.63.129.16 breaks DNS and load balancer probes.
- **Outbound TCP port 25** is blocked for most subscription types created after November 15, 2017 (Enterprise Agreement subscriptions aren't blocked). Use an SMTP relay on 587.
- **NSG flow logs retire on September 30, 2027** and can't be created any more; use **virtual network flow logs**.

## Routes

- Each subnet gets **system routes**: the VNet's own space (`VirtualNetwork`), `0.0.0.0/0` → `Internet`, and RFC 1918, `100.64.0.0/10` and other reserved ranges → **None** (dropped) until they're in your address space. Peering and gateways add more.
- **Selection:** longest prefix match first; for the same prefix, **user-defined route > BGP route > system route**. System routes for the VNet, peerings and service endpoints are preferred even over more specific BGP routes.
- **Next hop types** you set in a UDR: `VirtualAppliance` (an NVA or firewall IP), `VirtualNetworkGateway`, `Internet`, `VnetLocal`, `None` (drop).
- **Forced tunneling** (`0.0.0.0/0` → firewall) also sends Azure service traffic through the firewall unless service endpoints or private endpoints give it a more specific path.

## The private endpoint /32 route

Every private endpoint adds a **/32 route with next hop `InterfaceEndpoint`** to its VNet. Longest prefix wins, so a UDR like `10.0.0.0/8 → VirtualAppliance` or `0.0.0.0/0 → firewall` **does not** catch traffic to the endpoint; it goes straight there, bypassing inspection. To force it through a firewall:

1. Set `privateEndpointNetworkPolicies` on the **endpoint's subnet** to `RouteTableEnabled` or `Enabled` (default `Disabled`); `NetworkSecurityGroupEnabled` makes NSGs apply to endpoints.
2. Add a UDR whose prefix is **equal to or more specific than the VNet's address space** (a `0.0.0.0/0` route is too broad).

`az network watcher show-next-hop` returning `InterfaceEndpoint` for an endpoint's IP is this route at work.

## Check the effective result

```bash
az network nic show-effective-route-table -g <rg> -n <nic> -o table
az network nic list-effective-nsg -g <rg> -n <nic>
```

These need the VM running. The full diagnosis order: `guides/networking/diagnose-connectivity.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
