Azure Subnet NSG vs NIC NSG: Why the Packet Still Got Denied
▶ Watch on YouTube & subscribe to The Stack Underflow
An NSG can be attached to a subnet, to a server’s network card (NIC), or to both. When a packet meets two guards, which one wins? The video builds a small shop network (two web servers, a database and an admin jump box) and sends six packets through it until the answer is obvious. This page walks the same packets with every rule and the Microsoft documentation behind them.
The one-line version: inbound, the subnet’s NSG goes first, then the NIC’s; outbound, the reverse. Every NSG on the path must allow the packet, and each one ends with its own default rules.
Last verified against Microsoft Learn: 1 October 2026.
The order of the guards
Microsoft documents a fixed order:
| Direction | First | Second |
|---|---|---|
| Inbound | NSG on the subnet | NSG on the network interface |
| Outbound | NSG on the network interface | NSG on the subnet |
The same order applies to traffic between VMs in the same subnet. If the first NSG denies, the second never evaluates the packet. To let traffic in, both must allow it.
Each NSG is complete on its own: it has its own custom rules and its own default rules (65000 AllowVNetInBound, 65001 AllowAzureLoadBalancerInBound, 65500 DenyAllInbound, and three outbound). That detail decides packet 2.
A design note. Microsoft’s guidance today is to avoid associating NSGs with both a subnet and its network interfaces at the same time, because overlapping rules cause filtering problems that are hard to troubleshoot. The video layers them on purpose, to show the order.
Application security groups
An application security group (ASG) is a named group of NICs. You put each server’s NIC into a group (like web-servers or db-servers) and write rules that name the group instead of IP addresses. The rule then follows the servers, not their addresses.
- A rule that names an ASG applies only to NICs that are members of it. A NIC that isn’t a member isn’t affected, even if the NSG is on its subnet.
- All NICs in one ASG must be in the same virtual network, and when a rule uses ASGs as both source and destination, both groups must be in the same VNet.
- A rule can’t name multiple service tags or ASGs in one field.
- A NIC can belong to more than one ASG.
The shop network
This network was written for the video (it isn’t a Microsoft template). One VNet, 10.20.0.0/16:
| Server | Subnet | Address | ASG | NIC NSG |
|---|---|---|---|---|
| web-1 | web 10.20.1.0/24 | 10.20.1.4 | web-servers | web-1-nic-nsg |
| web-2 | web 10.20.1.0/24 | 10.20.1.5 | web-servers | none |
| db-1 | db 10.20.2.0/24 | 10.20.2.4 | db-servers | none |
| jump-1 | admin 10.20.9.0/24 | 10.20.9.4 | none | none |
web-1 and web-2 have Standard public IPs. The admin subnet has no NSG.
| NSG | Rule | Matches | Access |
|---|---|---|---|
| web subnet NSG | 100 Allow-HTTPS-Internet | TCP 443 from Internet | Allow |
| web subnet NSG | 110 Allow-SSH-Admin | TCP 22 from 10.20.9.0/24 | Allow |
| db subnet NSG | 100 Allow-SQL-From-Web | TCP 1433, ASG web-servers → ASG db-servers | Allow |
| db subnet NSG | 4000 Deny-VNet-Inbound | anything, VirtualNetwork → VirtualNetwork | Deny |
| web-1 NIC NSG | 100 Deny-SSH | TCP 22 from anywhere | Deny |
All of these are inbound rules. None of the NSGs has custom outbound rules, so their default outbound rules apply.
Six packets, step by step
Packet 1: a customer opens the shop on web-2. 203.0.113.25 → web-2, TCP 443. Azure translates web-2’s public IP to 10.20.1.5 before any NSG sees it. web subnet NSG: rule 100 matches. web-2’s NIC has no NSG. Allowed by web subnet NSG rule 100.
Packet 2: the same customer, on web-1. 203.0.113.25 → web-1 (10.20.1.4), TCP 443. web subnet NSG: rule 100 allows it, as before. Then web-1’s NIC NSG checks it: rule 100 Deny-SSH is for port 22, not 443, so no match. No other custom rule exists, so that NSG’s own default rules decide. The source is the Internet, not the VNet, so 65000 doesn’t match, and DenyAllInbound (65500) blocks it. Denied by web-1 NIC NSG rule 65500. The subnet said yes; the NIC said no.
Packet 3: the admin connects to web-2 with SSH. jump-1 10.20.9.4 → web-2 10.20.1.5, TCP 22.
The system route for 10.20.0.0/16 is the most specific, so the packet stays in the VNet. jump-1’s NIC and the admin subnet have no NSG. web subnet NSG: rule 100 is for 443, no match; rule 110 Allow-SSH-Admin matches. web-2’s NIC has no NSG. Allowed by web subnet NSG rule 110.
Packet 4: the admin connects to web-1 with SSH. jump-1 → web-1 10.20.1.4, TCP 22. web subnet NSG allows it with rule 110, just as before. Then web-1’s NIC NSG: rule 100 Deny-SSH matches. Denied by web-1 NIC NSG rule 100. Inbound traffic meets the subnet NSG first and the NIC’s second; the subnet allowed SSH from the admin subnet, but web-1’s own NSG denies it.
Packet 5: web-2 queries the database. web-2 10.20.1.5 → db-1 10.20.2.4, TCP 1433.
Leaving: web-2’s NIC has no NSG; web subnet NSG has no outbound rules, so AllowVnetOutBound (65000) allows it. Arriving: db subnet NSG rule 100 Allow-SQL-From-Web matches, because web-2 is in web-servers and db-1 is in db-servers. Allowed by db subnet NSG rule 100. The rule names groups, not addresses: add a new web server’s NIC to web-servers and it’s allowed too, without touching the rule.
Packet 6: the jump box tries the database directly. jump-1 10.20.9.4 → db-1, TCP 1433.
No NSG on jump-1’s NIC or the admin subnet. db subnet NSG: rule 100 needs a source in web-servers, and jump-1 isn’t a member, so no match. Rule 4000 Deny-VNet-Inbound matches. Denied by db subnet NSG rule 4000. Without rule 4000, the default AllowVNetInBound (65000) would have let the jump box in.
| # | Packet | Verdict | Decided by |
|---|---|---|---|
| 1 | Internet → web-2, TCP 443 | Allowed | web subnet NSG 100 |
| 2 | Internet → web-1, TCP 443 | Denied | web-1 NIC NSG 65500 DenyAllInbound |
| 3 | jump-1 → web-2, TCP 22 | Allowed | web subnet NSG 110 |
| 4 | jump-1 → web-1, TCP 22 | Denied | web-1 NIC NSG 100 Deny-SSH |
| 5 | web-2 → db-1, TCP 1433 | Allowed | db subnet NSG 100 (ASGs) |
| 6 | jump-1 → db-1, TCP 1433 | Denied | db subnet NSG 4000 |
What to remember
- Inbound: subnet NSG, then NIC NSG. Outbound: the reverse.
- Every NSG on the path must allow the packet, and each has its own default rules at the bottom.
- ASGs let a rule follow servers instead of addresses.
- To stop traffic inside the VNet, write your own deny with a number below 65000.
Pause & Prove: the questions from the video
1. The pinned question
The web subnet’s NSG allows HTTPS from the Internet at priority 100. web-1’s NIC has its own NSG with a single rule: deny SSH (port 22). A customer opens HTTPS to web-1. Allowed or denied, and by which rule?
Denied, by web-1’s NIC NSG, rule 65500 DenyAllInbound. The subnet NSG allows it, but inbound traffic must also pass the NIC’s NSG. That NSG has no rule allowing 443, so its own default rules decide.
2. The Community poll
A packet comes in to a VM whose subnet and network card both have an NSG. Which NSG checks it first?
- The network card’s NSG. That’s the order for outbound traffic.
- The subnet’s NSG. ✓ Inbound: subnet first, then the NIC.
- Whichever has the lower rule number. Priority numbers order rules inside one NSG, not NSGs against each other.
- Both at the same time, and allow wins. They’re evaluated in sequence, and both must allow.
Related Shorts
- The subnet NSG allowed it. The VM still denied it. (packet 2)
- Azure NSG rules without IP addresses: application security groups (packet 5)
- How to stop VMs in the same Azure VNet talking to each other (packet 6)
Before / after this video
- Before: How Azure NSGs Allow or Deny a Packet (video 1) and Azure Route Tables and NVAs (video 2)
- After: How Azure Firewall Decides: 5 Packets Through a Hub and Spoke (video 4)
Sources
Read on 1 October 2026:
- How network security groups filter network traffic: inbound subnet → NIC, outbound NIC → subnet, intra-subnet uses the same order, a deny at the first NSG stops evaluation, the tip to avoid NSGs on both subnet and NIC
- Azure network security groups overview: default rules, first match, NAT before inbound processing, one service tag or ASG per rule field
- Application security groups: what ASGs are, rules apply only to member NICs, same-VNet constraints, NICs in multiple ASGs
- Azure service tags overview: what the VirtualNetwork and Internet tags contain
- Azure virtual network traffic routing: system routes and longest prefix match
Change notes
- 1 Oct 2026: first published.
Not affiliated with or endorsed by Microsoft. Found a mistake? Tell us in the video’s comments and we’ll correct this page.
Found this useful? The deep version lives on YouTube — new breakdowns of how AI dev tools actually work, weekly.
Subscribe on YouTube →Prefer email? Get the free newsletter: one failure, traced step by step, about once a week.