Practical engineering guidance
Private endpoints, service endpoints and the DNS work that decides both
A private endpoint is a network interface and a DNS problem. Almost every failure I have seen was the DNS half, resolving the public address from somewhere nobody checked.
Series: Azure architecture
Two Azure features restrict a platform service to your network, they sound similar, and they work in fundamentally different ways. Choosing between them is straightforward once the mechanism is clear. Making the chosen one work reliably is almost entirely a DNS exercise, and that is where the time goes.
The problem both features address
An Azure platform service — a storage account, a SQL database, a key vault — is created with a public endpoint and a public DNS name. Access is controlled by identity and by the service firewall, but the endpoint exists on the internet.
For many organisations that is unacceptable, either from policy or from a genuine assessment of the risk. The two answers Azure offers are service endpoints and private endpoints.
How they actually differ
Service endpoints extend your virtual network’s identity to the service. Traffic leaves via an optimised route on the Azure backbone, and the service firewall can be configured to accept traffic only from named subnets. The service keeps its public IP address and its public DNS name; what changes is that the service now recognises your subnet as the source and can restrict on that basis.
The consequences:
- No DNS change. The name resolves publicly, as before. This is why service endpoints are simple.
- The endpoint is still public, just firewalled to your subnets.
- It does not work from on premises. Your datacentre is not in a virtual network subnet, so a service-endpoint restriction blocks it.
- It is per service, not per instance. The restriction applies to the service across the subnet, which is a coarser boundary than people often realise.
Private endpoints are a different mechanism entirely. A network interface is created in your subnet, with a private address from your address space, mapped to a specific instance of a specific service — this storage account, this database — and often to a specific sub-resource, such as blob or file.
The consequences:
- A genuinely private address, reachable from your network and, via ExpressRoute or VPN, from on premises.
- Per instance and per sub-resource, which is a much more precise boundary.
- The public endpoint should be disabled separately. Creating a private endpoint does not by itself stop public access — that is a separate setting on the service, and leaving it on is an extremely common gap.
- DNS must be changed, because the public name still resolves to the public address by default. This is the whole difficulty.
For anything holding data you care about, private endpoints are the right answer. Service endpoints remain reasonable for lower-sensitivity cases where the simplicity is worth it, and where on-premises access is not required.
The DNS mechanism, which is the actual work
When you create a private endpoint, Azure does not change what
contosostorage.blob.core.windows.net resolves to. Public DNS continues to return the public
address, and it must, because that name is shared with the rest of the world.
The redirection works through a specific chain, and every part of it has to be right:
- The public name becomes a CNAME to a private link name — for blob storage, something
under
privatelink.blob.core.windows.net. - You host a private DNS zone for
privatelink.blob.core.windows.netin Azure. - That zone contains an A record mapping your instance to the private endpoint’s address.
- The zone is linked to the virtual networks whose clients should get the private answer.
- A private DNS zone group on the private endpoint keeps that A record correct automatically. Without it, you are maintaining records by hand and they will drift.
The result: a client inside a linked virtual network follows the CNAME, finds the private zone, and gets the private address. A client outside follows the same CNAME, does not have the private zone, and gets the public address.
That last sentence is the source of nearly every private endpoint problem.
The failures, in the order I meet them
On-premises clients resolve the public address. Your datacentre’s DNS servers are not
using the Azure private zone. The fix is a DNS forwarder in Azure — a resolver in a hub
virtual network that the private zone is linked to — with on-premises DNS conditionally
forwarding the relevant privatelink zones to it. This is why DNS is a hub service, as noted
in hub-and-spoke in Azure.
A spoke works and another does not. The private DNS zone is linked to one virtual network and not the other. Zone links are per virtual network and are easy to forget when a spoke is added.
It worked and then stopped. The private endpoint was recreated with a different address and the A record was maintained manually. Use a private DNS zone group.
The wrong zone name. Each service has its own private link zone name, and some services have several for different sub-resources. Storage alone has separate zones for blob, file, queue, table and others. Using the wrong one produces a zone that resolves nothing while looking entirely correct.
Public access was never disabled. The private endpoint works, the application uses it, and the service is still reachable from the internet. Private endpoints and public network access are independent settings.
A custom DNS server in the virtual network. Virtual networks configured with custom DNS servers do not use Azure-provided DNS, so the private zone is not consulted unless those servers forward appropriately. This is extremely common in hybrid environments and is usually the answer when resolution works from one subnet and not another.
Implementation considerations
Centralise the private DNS zones. One set of zones, in a hub or a dedicated subscription, linked to every virtual network that needs them. Per-spoke zones produce inconsistent resolution and are a maintenance burden.
Enforce the zone group with policy. A deployIfNotExists policy that attaches private
endpoints to the correct private DNS zone group removes the most common cause of drift. This
is one of the better uses of the technique in
Azure Policy as a guardrail.
Plan the subnet. Private endpoints consume addresses from the subnet they live in. An estate that adopts them broadly will consume more addresses than the initial design allowed.
Disable public network access explicitly, and audit for it. This deserves a policy in audit mode across the estate, because the gap is silent.
Know that some services do not support private endpoints, or support them only on certain tiers. Check per service rather than assuming, and check what sub-resources exist — you may need more than one endpoint for a single resource.
Validation
Test resolution from every network that matters, not just the one you built it from:
# From a VM in each relevant virtual network, and from an on-premises host.
Resolve-DnsName -Name 'contosostorage.blob.core.windows.net'
The answer should be a private address from your own space, reached via a CNAME to the
privatelink name. If you get a public address, you have found the problem and the question
is which link in the chain is missing for that client.
Then verify the negative case, which is the one people skip: from outside your network, confirm the service is actually unreachable. A private endpoint that works alongside an enabled public endpoint has added a network path, not removed one.
Finally, confirm connectivity end to end rather than only resolution — name resolution and network reachability are separate failures, and an NSG or route can block a correctly resolved private address.
Rollback
Removing a private endpoint and re-enabling public access restores the previous behaviour, subject to DNS caching on clients. Keep that in mind during a cutover: a client that cached the private address will not immediately follow a change back, and vice versa.
The change with the sharpest edge is disabling public network access, because anything you did not know was connecting stops instantly — a monitoring tool, a partner integration, a developer’s machine. Audit connections before disabling it rather than after.
Verification and limits
The distinction between service endpoints and private endpoints, the CNAME-to-privatelink resolution chain, private DNS zone links and zone groups, the independence of private endpoints from the public network access setting, and per-service sub-resource zones were checked against current Microsoft documentation on 20 September 2026.
Nothing here was deployed or tested for this article. Disabling public network access and changing DNS resolution both break connectivity for anything you have not inventoried — audit existing connections first, change one environment at a time, and confirm resolution from every network that needs it, including on premises. Zone names and per-service support change, so confirm the correct zone for each service at the time you deploy.
References
Reader feedback
Was this article useful?
No ratings yet. Be the first to rate this article.
