Every private endpoint needs the right privatelink.* private DNS zone, or clients keep
resolving the public IP and traffic never enters the endpoint. This page is the printable
version of the Private Endpoint DNS Zones tool,
which deduplicates zones across a selection and generates the az cli commands for you.
How the redirection works
The service's public DNS name gains a CNAME into the matching privatelink.* name once a
private endpoint exists. Public resolvers follow the chain back out to a public A record;
resolvers that can see the private zone answer with the endpoint's private IP:
myvault.vault.azure.net
→ CNAME myvault.privatelink.vaultcore.azure.net
→ private zone linked to your VNet? A 10.x.x.x (private endpoint)
→ otherwise A <public IP> (or refusal, if public access is off)
Two consequences worth memorising: the zone must be linked to every VNet whose
resolvers should see it (or reachable via your central DNS), and on-prem clients must
forward the public zone (e.g. vault.azure.net) to a resolver inside Azure — you
cannot forward privatelink.* directly, because on-prem clients never see that name
until the CNAME redirects them.
Zones by service
Storage
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| Blob Storage | blob |
privatelink.blob.core.windows.net |
blob.core.windows.net |
| File shares | file |
privatelink.file.core.windows.net |
file.core.windows.net |
| Queues | queue |
privatelink.queue.core.windows.net |
queue.core.windows.net |
| Tables | table |
privatelink.table.core.windows.net |
table.core.windows.net |
| Static website | web |
privatelink.web.core.windows.net |
web.core.windows.net |
| Data Lake Gen2 | dfs |
privatelink.dfs.core.windows.net |
dfs.core.windows.net |
Databases
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| SQL Database / Managed Instance | sqlServer |
privatelink.database.windows.net |
database.windows.net |
| PostgreSQL Flexible Server | postgresqlServer |
privatelink.postgres.database.azure.com |
postgres.database.azure.com |
| MySQL Flexible Server | mysqlServer |
privatelink.mysql.database.azure.com |
mysql.database.azure.com |
| Cosmos DB (NoSQL) | Sql |
privatelink.documents.azure.com |
documents.azure.com |
| Cosmos DB (MongoDB) | MongoDB |
privatelink.mongo.cosmos.azure.com |
mongo.cosmos.azure.com |
| Cosmos DB (Cassandra) | Cassandra |
privatelink.cassandra.cosmos.azure.com |
cassandra.cosmos.azure.com |
| Cosmos DB (Gremlin) | Gremlin |
privatelink.gremlin.cosmos.azure.com |
gremlin.cosmos.azure.com |
| Cosmos DB (Table) | Table |
privatelink.table.cosmos.azure.com |
table.cosmos.azure.com |
| Cache for Redis | redisCache |
privatelink.redis.cache.windows.net |
redis.cache.windows.net |
Security
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| Key Vault | vault |
privatelink.vaultcore.azure.net |
vault.azure.net |
| Key Vault Managed HSM | managedhsm |
privatelink.managedhsm.azure.net |
managedhsm.azure.net |
Compute & containers
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| AKS private cluster (API server) | management |
privatelink.{region}.azmk8s.io |
{region}.azmk8s.io |
| Container Registry | registry |
privatelink.azurecr.io |
azurecr.io |
| App Service / Functions | sites |
privatelink.azurewebsites.net |
azurewebsites.net |
| Azure Databricks | databricks_ui_api |
privatelink.azuredatabricks.net |
azuredatabricks.net |
Notes: replace {region} with the resource's region (e.g. privatelink.westeurope.azmk8s.io).
Container Registry data-endpoint records (<registry>.<region>.data) live in the same zone.
App Service also needs the <app>.scm record for Kudu/deployments — same zone.
Integration & messaging
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| Service Bus | namespace |
privatelink.servicebus.windows.net |
servicebus.windows.net |
| Event Hubs | namespace |
privatelink.servicebus.windows.net (shared) |
servicebus.windows.net |
| Event Grid (topics/domains) | topic |
privatelink.eventgrid.azure.net |
eventgrid.azure.net |
| IoT Hub | iotHub |
privatelink.azure-devices.net + privatelink.servicebus.windows.net |
azure-devices.net |
| SignalR Service | signalr |
privatelink.service.signalr.net |
service.signalr.net |
| Data Factory | dataFactory |
privatelink.datafactory.azure.net |
datafactory.azure.net |
| Data Factory (portal) | portal |
privatelink.adf.azure.com |
adf.azure.com |
| API Management | Gateway |
privatelink.azure-api.net |
azure-api.net |
Management & monitoring
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| Azure Monitor / Log Analytics / App Insights (AMPLS) | azuremonitor |
privatelink.monitor.azure.com + privatelink.oms.opinsights.azure.com + privatelink.ods.opinsights.azure.com + privatelink.agentsvc.azure-automation.net + privatelink.blob.core.windows.net |
monitor.azure.com (and friends) |
| Automation | Webhook / DSCAndHybridWorker |
privatelink.azure-automation.net |
azure-automation.net |
| Backup (Recovery Services) | AzureBackup |
privatelink.{geo}.backup.windowsazure.com + blob + queue zones |
{geo}.backup.windowsazure.com |
| App Configuration | configurationStores |
privatelink.azconfig.io |
azconfig.io |
{geo} is the vault's geo code, e.g. weu for West Europe. An Azure Monitor Private
Link Scope needs all five zones — a partial set produces maddening partially-working
telemetry.
AI & analytics
| Service | Sub-resource | Private DNS zone | Public zone to forward |
|---|---|---|---|
| Azure OpenAI | account |
privatelink.openai.azure.com |
openai.azure.com |
| AI Services (Cognitive Services) | account |
privatelink.cognitiveservices.azure.com |
cognitiveservices.azure.com |
| AI Search | searchService |
privatelink.search.windows.net |
search.windows.net |
| Machine Learning workspace | amlworkspace |
privatelink.api.azureml.ms + privatelink.notebooks.azure.net |
api.azureml.ms |
| Synapse (SQL pools) | Sql / SqlOnDemand |
privatelink.sql.azuresynapse.net |
sql.azuresynapse.net |
| Synapse (workspace dev) | Dev |
privatelink.dev.azuresynapse.net |
dev.azuresynapse.net |
Setup commands
# Create a zone (once per DNS environment, not per endpoint)
az network private-dns zone create -g <rg> -n "privatelink.blob.core.windows.net"
# Link it to a VNet (once per VNet that must resolve it)
az network private-dns link vnet create -g <rg> -z "privatelink.blob.core.windows.net" \
-n <link-name> --virtual-network <vnet-id> --registration-enabled false
# Attach the zone to a private endpoint (creates/maintains the A record)
az network private-endpoint dns-zone-group create -g <rg> \
--endpoint-name <pe-name> -n default \
--private-dns-zone <zone-id> --zone-name <any-label>
Audit what already exists
Before creating anything, find the zones and links you already have — duplicate zones are the number-one cause of "it resolves from this VNet but not that one".
# Every private DNS zone in the subscription, with how many VNets each is linked to
az network private-dns zone list \
--query "[].{zone:name, rg:resourceGroup, links:numberOfVirtualNetworkLinks, records:numberOfRecordSets}" -o table
# Same, scoped to a resource group
az network private-dns zone list -g <rg> -o table
# Which VNets a given zone is linked to
az network private-dns link vnet list -g <rg> -z "privatelink.vaultcore.azure.net" \
--query "[].{link:name, vnet:virtualNetwork.id, state:virtualNetworkLinkState}" -o table
# The A records a zone currently holds (one per private endpoint attached to it)
az network private-dns record-set a list -g <rg> -z "privatelink.vaultcore.azure.net" -o table
# Which zone group (and therefore which zone) a private endpoint writes into
az network private-endpoint dns-zone-group list -g <rg> --endpoint-name <pe-name> -o table
# All private endpoints in a resource group and the sub-resource each targets
az network private-endpoint list -g <rg> \
--query "[].{name:name, target:privateLinkServiceConnections[0].groupIds[0]}" -o table
A zone with links: 0 is dead weight; a zone name that appears twice across resource groups is
the split-brain to fix first.
Gotchas
- One zone per DNS environment, not per endpoint. Duplicate
privatelink.*zones in every spoke is the classic anti-pattern — records fragment and resolution depends on which VNet asks. Centralize (hub or dedicated DNS subscription) and link outward. - Zone linked but not to the right VNet — resolution comes from whatever the client's DNS server's VNet sees, not the client's own VNet. With custom DNS servers or a Private Resolver, the zone must be linked to that VNet.
- Don't create records by hand. Use the endpoint's DNS zone group so the A record is created, updated and deleted with the endpoint.
- Verify from both sides: inside Azure
nslookup myvault.vault.azure.netshould return10.x.x.x; from the internet it should not. Check the outside view with the DNS Record Lookup and decode any confusing resolver output with the dig & nslookup Output Explainer. - Services with unstable or partitioned zone schemes are omitted here — verify anything exotic against Microsoft Learn's private endpoint DNS zone table.