An Azure service that enables hosting Domain Name System (DNS) domains in Azure.
Hello Ahmad Yousef,
Greetings! Thanks for raising this question in the Q&A forum.
The most likely root cause here is that your Domain Controller VMs are acting as the DNS servers for your VNets (a very common setup), and Azure Private DNS zones only get consulted automatically for the VNet where the query actually lands, which is your DC's VNet, not the client VM's VNet. If your DC VNet has been linked to the Prod Private DNS zone but not to the Clone Private DNS zone, that would explain exactly the behavior you're seeing: resolution works from Prod because the chain (App VM to DC to Azure DNS 168.63.129.16) can see the Prod zone, but the same chain fails for Clone because the DC has no route into the Clone zone's records.
Please check these in order:
Confirm how your VMs actually resolve DNS Check the DNS server setting on the Prod and Clone app VM NICs (or the VNet-level DNS servers setting). If they point to your Domain Controller IP addresses rather than Default (Azure-provided), then your DCs are the resolvers, and everything below is about the DC's path, not the app VM's own VNet link.
Verify the Private DNS zone Virtual Network Links, per zone For each Private DNS zone (Prod's and Clone's), go to the zone resource, open Virtual network links, and confirm which VNets are linked. Do this for both zones and compare side by side. A missing link on the Clone zone, or a link that exists but with autoregistration only pointed at the wrong VNet, is the most common cause of this exact symptom.
Add the DC VNet as a resolution VNet on the Clone zone (yes, this is the fix you're asking about) Since your DCs sit in a separate VNet used for domain services, and they need to be able to resolve records in the Clone Private DNS zone, you do want to add a virtual network link from the DC VNet to the Clone zone. Autoregistration is not needed for this link, since the DC VNet isn't hosting the Postgres resource itself, only forwarding queries:
az network private-dns link vnet create \
--resource-group <clone-dns-zone-rg> \
--zone-name <clone-private-dns-zone-name> \
--name dc-vnet-link \
--virtual-network <dc-vnet-resource-id> \
--registration-enabled false
Confirm the conditional forwarder exists on the DC for the Clone zone's domain suffix If your DCs use Windows DNS with conditional forwarders (rather than every VM pointing straight at Azure DNS), check that a conditional forwarder for the Clone Postgres private DNS zone's domain name exists and points to 168.63.129.16. It's easy to set this up for Prod and forget to replicate it for Clone.
Confirm the A record actually exists in the Clone zone Open the Clone Private DNS zone and confirm the A record for your Clone Postgres instance is present and matches the private endpoint's current IP. If the Postgres Flexible Server or the private endpoint integration didn't finish provisioning cleanly, the record itself may be missing even though the zone and links are otherwise fine.
Check VNet peering and NSGs between the DC VNet and the Clone VNet Since DNS queries have to physically reach the DC and back, confirm peering exists between the DC VNet and Clone VNet (if they're separate), and that no NSG is blocking UDP/TCP port 53 between them. DNS queries to 168.63.129.16 itself are always permitted by the platform, but the hop from your app VM to your DC VM is regular network traffic and can be blocked like any other.
To isolate exactly where the break is, run this from the Clone app VM and compare it against the same test from Prod:
nslookup <postgres-fqdn> <dc-ip-address>
nslookup <postgres-fqdn> 168.63.129.16
If the first fails but the second succeeds, the problem is entirely in the DC's forwarding or its VNet link. If both fail, the zone's VNet link or A record is the issue.
If this answer helps you kindly accept the answer which will help others who have similar questions.
Best Regards,
Jerald Felix.