---
cuppy_hub: azure
cuppy_path: reference/networking/private-endpoints-and-dns.md
cuppy_section: docs
cuppy_doc: Z447-M4P9
cuppy_doc_uuid: dc0c6921-4677-408a-9907-cbd5d2d96d0c
cuppy_permalink: https://cuppy.io/azure/d/Z447-M4P9
cuppy_version: 1
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/azure/docs/reference/networking/private-endpoints-and-dns
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: eba85b9705f466e4a1438f66e49d882530d5f45ea191bb615fd71c1b4b91b298
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Private endpoints and private DNS

**A private endpoint is a NIC with a private IP for one resource and one sub-resource (`groupId`).** Clients keep using the normal hostname (`<acct>.blob.core.windows.net`): once the endpoint exists, public DNS returns a CNAME to `<acct>.privatelink.blob.core.windows.net`, and a **private DNS zone** for `privatelink.blob.core.windows.net`, linked to the client's VNet, answers that name with the private IP. Without the zone link the same CNAME resolves to the public IP, and a service with public access disabled answers **403**.

## Zones for common services (global Azure)

| Service (`groupId`) | Private DNS zone(s) |
|---|---|
| Storage `blob`, `dfs`, `file`, `queue`, `table`, `web` | `privatelink.blob.core.windows.net`, `privatelink.dfs.core.windows.net`, `privatelink.file.core.windows.net`, `privatelink.queue.core.windows.net`, `privatelink.table.core.windows.net`, `privatelink.web.core.windows.net` |
| Key Vault `vault` | `privatelink.vaultcore.azure.net` |
| Container Registry `registry` | `privatelink.azurecr.io` and `{region}.data.privatelink.azurecr.io` |
| Azure SQL `sqlServer` | `privatelink.database.windows.net` |
| Cosmos DB `Sql` | `privatelink.documents.azure.com` |
| PostgreSQL / MySQL flexible server | `privatelink.postgres.database.azure.com` / `privatelink.mysql.database.azure.com` |
| Azure Managed Redis `redisEnterprise`; Azure Cache for Redis `redisCache` | `privatelink.redis.azure.net`; `privatelink.redis.cache.windows.net` |
| App Service and Functions `sites` | `privatelink.azurewebsites.net` (and `scm.privatelink.azurewebsites.net`) |
| Container Apps environment `managedEnvironments` | `privatelink.{regionName}.azurecontainerapps.io` |
| Service Bus, Event Hubs `namespace` | `privatelink.servicebus.windows.net` |
| Foundry Tools / Azure OpenAI `account` | `privatelink.cognitiveservices.azure.com`, `privatelink.openai.azure.com`, `privatelink.services.ai.azure.com` |
| AI Search `searchService`; App Configuration `configurationStores` | `privatelink.search.windows.net`; `privatelink.azconfig.io` |
| Azure Monitor private link scope | `privatelink.monitor.azure.com` plus the `opinsights` and agent zones |

The full list, and the zones for other clouds, is Microsoft's "Azure Private Endpoint DNS zone values" page. **One zone per name, shared by every VNet**: create each zone once (usually in a hub subscription) and link it to every VNet that resolves it; two zones with the same name in different places split resolution.

## Making DNS answer correctly

- **Zone group** on the endpoint (`privateDnsZoneGroups`): Azure writes the A records, updates them when the endpoint changes, and deletes them with the endpoint. Up to five zones per group, one zone per name. Without it you script the records yourself.
- **VNet link** (`privateDnsZones/virtualNetworkLinks`) from the zone to each client VNet, `registrationEnabled: false`. A peered VNet needs its own link: default resolution doesn't cross peerings.
- **Custom DNS servers** in the VNet must forward to Azure DNS, **168.63.129.16**, from inside a VNet linked to the zones. Conditional forwarders name the **public** zone (`blob.core.windows.net`, `database.windows.net`), not the `privatelink.` one.
- **On-premises clients:** an Azure DNS Private Resolver inbound endpoint (or a DNS server VM) in a linked VNet, with on-premises conditional forwarders pointing at it.
- **NXDOMAIN inside the VNet** for a name that resolves publicly: the linked privatelink zone has no record for it (for example a second storage account whose endpoint lives in another zone). Add the record through a zone group, or set the link's `resolutionPolicy: NxDomainRedirect` (privatelink zones only), which falls back to public resolution. Negative answers are cached for a few minutes after a fix.
- Some clients also query **AAAA**: a private endpoint answers A only.

## Approval, roles and network policies

- A connection is **auto-approved** when the creator has `privateEndpointConnectionsApproval/action` on the target (for example Storage Account Contributor, Key Vault Contributor, SQL Server Contributor, DocumentDB Account Contributor). Otherwise, or across tenants, it stays **Pending** until the resource owner approves it (`az network private-endpoint-connection approve`). Endpoints created by Front Door Premium, App Service, Synapse or Data Factory managed VNets always need approval on the target.
- The creator needs `Microsoft.Network/privateEndpoints/write` where the endpoint goes, `Microsoft.Network/virtualNetworks/subnets/join/action` on the subnet (Network Contributor), and **Private DNS Zone Contributor** on the zone for the zone group.
- The endpoint's subnet must **not be delegated**. `privateEndpointNetworkPolicies` (`Disabled` by default) decides whether NSGs and UDRs apply to endpoints: `reference/networking/nsgs-and-routes.md`.
- **Limits:** about 1,000 private endpoints per VNet (more needs the High Scale feature), and one Private Link Service per load balancer frontend IP. Read your counts; don't design to the edge.

Errors: `reference/networking/errors.md`. Bicep for one endpoint with its zone: `patterns/private-endpoint-for-paas.md`. Database-specific network modes (PostgreSQL and MySQL private access vs endpoints, SQL Redirect ports): `patterns/app-to-database-with-managed-identity.md`.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 107 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/azure/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
