Home / Azure

AzureTroubleshootingIntermediate

Azure DNS public zone not resolving after delegation - NS records, registrar settings and record checks

Records exist in your Azure DNS zone but the internet returns NXDOMAIN, SERVFAIL or the old answer. Check delegation, child zones, DNSSEC and TTLs in order.

Deepak Bhardwaj8 min read

Applies toAzure DNS public zones, Azure CLI 2.60+, dig / nslookup / Resolve-DnsName

You created a public zone in Azure DNS, added the records, and the portal looks correct. But www.contoso.com still returns NXDOMAIN, SERVFAIL or the IP of the old hosting provider. In almost every case the zone itself is fine and the problem is in the chain that leads resolvers to it.

The fix order is always the same: prove Azure answers correctly, then prove the parent sends resolvers to Azure, then deal with caching.

Quick map: symptom, cause, fix

Symptom Likely cause Fix
NXDOMAIN or old answer from public resolvers, correct answer from ns1-0x.azure-dns.com Registrar still points at the old name servers Update NS at the registrar to the four Azure name servers
Correct answer only from some resolvers Old NS records cached (TTL up to 48 hours at the TLD) Wait out the TTL; don't change anything else
SERVFAIL from validating resolvers, dig +cd works DS record at the registrar doesn't match the zone's DNSSEC keys Remove or correct the DS record
Subdomain (dev.contoso.com) NXDOMAIN, parent works Child zone created but no NS record set in the parent zone Add the NS delegation in the parent
Record missing even when asking Azure directly Record created in the wrong zone, wrong name, or in a private zone Check az network dns record-set list on the right zone
Apex (contoso.com) can't point at Front Door/App Service CNAME not allowed at the apex Use an alias A record or the service's apex method
Changes in Azure not visible for hours Old record TTL still cached by resolvers Lower TTL before changes next time

Step 1: Ask Azure directly

Get the name servers assigned to your zone. Each zone gets four, and they differ between zones, so never copy them from another zone or from a document.

az network dns zone show -g rg-dns -n contoso.com --query nameServers -o tsv
# ns1-03.azure-dns.com.
# ns2-03.azure-dns.net.
# ns3-03.azure-dns.org.
# ns4-03.azure-dns.info.

Query one of them directly. This bypasses delegation and caching completely:

dig @ns1-03.azure-dns.com www.contoso.com A +norecurse
Resolve-DnsName www.contoso.com -Type A -Server ns1-03.azure-dns.com -DnsOnly
  • Correct answer: the zone is fine. Go to Step 2.
  • NXDOMAIN or wrong answer: the problem is in the zone. List what is actually there:
az network dns record-set list -g rg-dns -z contoso.com \
  --query "[].{name:name, type:type, ttl:ttl, fqdn:fqdn}" -o table

Common mistakes here: the record name includes the zone (www.contoso.com in a zone contoso.com creates www.contoso.com.contoso.com), the record is in a private DNS zone with the same name (az network private-dns ...), or there are two public zones with the same name in different subscriptions and you edited the one that isn't delegated.

Tip

Duplicate public zones are allowed in Azure, each with its own name server set. If Step 1 works but the registrar's name servers don't match nameServers from this zone, you are probably looking at the wrong copy.

Step 2: Check the delegation from the parent

Ask the TLD servers which name servers they hand out for your domain. dig +trace walks the chain from the root:

dig +trace www.contoso.com A

Or ask the TLD directly:

dig NS com. +short                          # pick one TLD server
dig @a.gtld-servers.net contoso.com NS +norecurse
Resolve-DnsName contoso.com -Type NS -Server a.gtld-servers.net -DnsOnly

Compare the result with the four Azure name servers from Step 1.

What the TLD returns Meaning
The four Azure servers for this zone Delegation is correct. Go to Step 3
The old provider's servers Registrar not updated. Change NS at the registrar
Azure servers, but a different number (ns1-01 instead of ns1-03) Pointed at another zone's name servers. Fix at the registrar
A mix of old and Azure servers Partial update. Resolvers will get different answers at random. Set all four Azure servers and remove the rest

The change is made at the registrar (the company you bought the domain from), not in Azure. Enter all four Azure name servers. Some registrar portals reject the trailing dot; leave it off if so.

Child zones (subdomain delegation)

If dev.contoso.com is a separate Azure zone, the parent zone contoso.com needs an NS record set named dev pointing at the child's name servers.

# Name servers of the child zone
az network dns zone show -g rg-dns -n dev.contoso.com --query nameServers -o tsv

# Create the delegation in the parent
for ns in $(az network dns zone show -g rg-dns -n dev.contoso.com --query "nameServers[]" -o tsv); do
  az network dns record-set ns add-record -g rg-dns -z contoso.com -n dev -d "$ns"
done

# Check it
az network dns record-set ns show -g rg-dns -z contoso.com -n dev -o json

If both zones are in the same subscription, az network dns zone create ... --parent-name contoso.com creates the delegation for you when you create the child.

Step 3: Check DNSSEC

A validating resolver returns SERVFAIL when the DS record at the registrar doesn't match the DNSKEY the zone is signed with. This often happens after a migration: the old provider's DS record was left at the registrar, and Azure is either not signing the zone or signing it with different keys.

dig contoso.com DS +short                   # DS at the parent
dig @ns1-03.azure-dns.com contoso.com DNSKEY +short
dig www.contoso.com A                       # SERVFAIL?
dig www.contoso.com A +cd                   # works with checking disabled -> DNSSEC problem

If +cd works and the normal query fails, it is DNSSEC. Either remove the DS record at the registrar or, if you've enabled DNSSEC signing on the Azure zone, publish the DS values Azure gives you for that zone (shown on the zone's DNSSEC page in the portal).

Caution

When moving a signed domain to Azure DNS, remove the old DS record and wait for its TTL to expire before changing NS. Changing NS with a stale DS in place makes the whole domain fail for every validating resolver, which includes most large public resolvers.

Step 4: Deal with caching

If the delegation is right and DNSSEC is clean, different resolvers may still give different answers for a while.

dig @8.8.8.8 www.contoso.com A      # note the TTL in the answer section
dig @1.1.1.1 www.contoso.com A

The TTL in the answer counts down to when that resolver will ask again. TLD NS records for .com are commonly cached for up to two days, so a delegation change can take that long to reach every resolver. Some public resolvers offer a cache flush page; your own corporate DNS servers can be flushed directly:

Clear-DnsServerCache -ComputerName dns01 -Force   # Windows DNS Server
Clear-DnsClientCache                              # local client

Step 5: Apex records for Azure services

You cannot put a CNAME at the zone apex. For an Azure resource with a public IP, Traffic Manager or Front Door, use an alias record so the record follows the resource:

az network dns record-set a create -g rg-dns -z contoso.com -n "@" \
  --target-resource /subscriptions/<sub>/resourceGroups/rg-web/providers/Microsoft.Network/publicIPAddresses/pip-web

Check the target service's documentation for apex support; App Service, for example, uses an A record plus a TXT validation record instead.

Prevent it next time

  • Lower TTLs two days before a cutover. Set record TTLs to 300 seconds ahead of a migration, then raise them after.
  • Copy name servers from the zone, not from memory. Script it with az network dns zone show --query nameServers.
  • One public zone per domain. Use Azure Policy or a Resource Graph query to find duplicates:
resources
| where type =~ 'microsoft.network/dnszones'
| summarize zones = count(), subs = make_set(subscriptionId) by name
| where zones > 1
  • Protect the zone. Put a CanNotDelete lock on production DNS zones and limit write access with the DNS Zone Contributor role.
  • Monitor resolution from outside. An Application Insights availability test or a simple external probe catches a broken delegation within minutes, not when customers call.