Seven posts of theory. This one is the lookup table.

A VM in Azure asks for a name. Where does the answer come from - the internet, Azure DNS, a private DNS zone, a privatelink zone, or a DNS server sitting in a datacentre three hundred kilometres away? And what exactly do you have to configure to make that happen?

Answer three or four questions below and you get the architecture, the steps, and the mistakes to avoid.

The decision tree

Interactive

Azure DNS resolution decision tree

Note

The tree above needs JavaScript. Everything it can tell you is also written out in the tables and the checklist below, so nothing is lost if you have it disabled or you are reading a printed copy.

The four questions behind it

Strip away the branches and the whole thing is four questions, asked in this order. Learning the order is more useful than memorising the outcomes.

  1. Where is the client? In a virtual network, or outside one. This decides whether the platform resolver is even in the path.
  2. What does the VNet's DNS servers setting say? Default means 168.63.129.16 and everything the platform can do. Custom means your servers own the answer and linked private zones are invisible unless you forward.
  3. What kind of name is it? Public, Azure private, privatelink, or on-premises. Each has exactly one mechanism.
  4. Who owns the record? You, Microsoft, or somebody else's tenant. This is the question that produces the NxDomainRedirect conversation.

Every path at a glance

The same tree, flattened, for when you already know where you are going.

ClientName being resolvedMechanismWhat you configure
Azure VMPublic internet nameAzure DNS recursionNothing - keep DNS servers on Default
Azure VMPublic name, custom DNS serversYour resolversForward to 168.63.129.16
Azure VMVM in the same VNetAzure-provided (internal.cloudapp.net)Nothing
Azure VMPrivate name, one VNetPrivate DNS zoneZone + virtual network link
Azure VMPrivate name, hub and spokePrivate DNS zoneOne zone, links to all spokes, or hub + resolver
Azure VMPrivate name, isolated VNetPrivate DNS zoneZone link (no peering needed)
Azure VMOwn Private Endpoint, one VNetprivatelink zoneZone + link + zone group + disable public access
Azure VMOwn Private Endpoint, at scaleprivatelink zoneHub zones + DeployIfNotExists policy
Azure VMPartner's Private Link resourceFallbackresolutionPolicy = NxDomainRedirect on the link
Azure VMOn-premises name, normal volumeForwarding rulesetResolver in hub, spokes point at inbound endpoint
Azure VMOn-premises name, very high QPSForwarding rulesetRuleset linked per spoke, DNS setting stays Default
Azure VMOn-premises name, isolated VNetForwarding rulesetWildcard ruleset linked to that VNet
On-premisesAzure private zone recordInbound endpointConditional forwarder for the zone suffix
On-premisesAzure Private EndpointInbound endpointConditional forwarder for the public suffix
On-premisesPublic Azure nameNormal public DNSNothing

The evaluation order, one more time

Every outcome above is a consequence of this sequence. When something resolves to the wrong address, walk it from the top and you will find the cause before you reach the bottom.

diagram
  Query from a VM
        β”‚
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ 1. VNet DNS servers = custom?               │──yes──▢ your servers answer.
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         Azure is out of the loop.
        β”‚ no (Default)
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ 2. Linked private DNS zone matches?         │──yes──▢ answered from the zone
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         (or NXDOMAIN, unless
        β”‚ no                                               NxDomainRedirect)
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ 3. Forwarding ruleset linked to this VNet?  │──match─▢ out via outbound endpoint
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          longest suffix wins
        β”‚ no match
        β–Ό
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚ 4. Azure DNS recursive lookup               │──────▢ public answer
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Two rules worth repeating because they cause most incidents:

Troubleshooting, in the order that finds it fastest

  1. What is the VM actually using as a resolver? Get-DnsClientServerAddress or resolvectl status. If it disagrees with the VNet setting, the DHCP lease is stale.
  2. Run dig or nslookup against 168.63.129.16 directly. If that works and the normal lookup does not, the problem is client-side.
  3. Follow the CNAME chain. Does the public name redirect into privatelink? Does privatelink resolve to a private IP?
  4. Is the zone name exactly the published one, and is it linked to this virtual network?
  5. Is there more than one zone with that name in the tenant? Check with Resource Graph.
  6. Is a private zone shadowing a forwarding rule for the same suffix?
  7. Is the private endpoint connection Approved? Perfect DNS and a Pending connection look identical from the client.
  8. Is there a route and a firewall opening for UDP and TCP 53, in both directions?
  9. Are you near the 10,000 QPS ceiling on an endpoint? Check Azure Monitor metrics before your users tell you.
  10. Turn on DNS query logging and stop guessing.

Closing the series

Eight posts, and it comes down to a handful of durable ideas:

If I had to compress all eight posts into one sentence: centralize DNS, and be able to draw the query path on a whiteboard. The architecture you can explain in thirty seconds is the one you will still be able to debug at 2 a.m.

Enjoy!