UK tech experts · info@vividrepairs.co.uk
Vivid Repairs
Linux terminal on a dark desk showing Azure VPN client DNS error output and systemd-resolved status commands
Fix It Yourself · Troubleshooting

Azure VPN DNS Linux

Published 25 August 202613 min read
As an Amazon Associate, we may earn from qualifying purchases. Our ranking is independent.

Azure VPN DNS Linux failures have been flooding support queues lately. The error is always the same: 'Couldn't set DNS server/domains', the tunnel looks like it connects, and then nothing internal resolves. The profile works fine on Windows. Here's what's actually broken and how to fix it.

TL;DR

Azure VPN DNS Linux failures are almost always caused by systemd-resolved not running or resolv.conf pointing at the wrong place. Enable systemd-resolved, relink resolv.conf to the stub resolver, restart NetworkManager, and reconnect. If private names still fail after that, the Azure VPN profile XML needs DNS suffixes added, or your Azure VNet needs a proper DNS forwarder.

⏳️ 13 min read ✅ 87% success rate 📅 Updated July 2026

Key Takeaways

  • Azure VPN DNS Linux errors come from a broken systemd-resolved integration, not the VPN profile itself.
  • The Azure VPN client uses DBus to push DNS settings. If systemd-resolved isn't running, that push fails immediately.
  • resolv.conf must be symlinked to /run/systemd/resolve/stub-resolv.conf, not pointing at a static file.
  • Azure DNS (168.63.129.16) is not routable over Point-to-Site tunnels. You need a custom DNS forwarder for private names.
  • Always re-download and re-import the VPN profile after any DNS change on the Azure side.

At a Glance

  • Difficulty: Easy to Medium
  • Time Required: 5 to 30 mins
  • Success Rate: 87% of users

What Causes Azure VPN DNS Linux Failures?

The error message 'Couldn't set DNS server/domains' is specific. It doesn't mean the tunnel failed to build. It means the Azure VPN client connected, tried to push DNS server addresses and domain suffixes into the Linux resolver stack via DBus, and got an error back. The tunnel may actually be up. DNS just isn't working.

On Windows this whole process is invisible because the OS handles VPN-supplied DNS settings natively. Linux doesn't do that. The Azure VPN client on Linux is built to talk specifically to systemd-resolved over DBus. If systemd-resolved isn't running, or if it's running but resolv.conf isn't pointing at its stub interface, the DBus call fails and you get the error. Simple as that.

There are a few variations of this problem worth knowing about:

  • systemd-resolved not enabled: Some minimal distro installs, custom server images, and older Ubuntu LTS setups ship without systemd-resolved active. The service exists but it's not started.
  • resolv.conf is a static file or wrong symlink: Many distros have resolv.conf pointing at /run/systemd/resolve/resolv.conf (the full upstream resolver list) rather than /run/systemd/resolve/stub-resolv.conf (the 127.0.0.53 stub). The Azure VPN client needs the stub path.
  • NetworkManager not delegating DNS: If NetworkManager's dns setting isn't set to systemd-resolved, DNS changes from the VPN never reach the active resolver at all.
  • Missing DNS suffixes in the profile: The Azure VPN profile XML may have no dnssuffixes entries for your private domains, so even when the resolver is healthy, it doesn't know which names to route through the tunnel.
  • Unreachable custom DNS server in Azure: Azure DNS (168.63.129.16) is not routable over Point-to-Site VPN. If your VNet is configured to use it directly, private name resolution will fail even when everything else is correct.

Most of the time it's the first two. Fix systemd-resolved and the symlink, and you're done in under ten minutes. The other causes only come up when the quick fix connects the VPN but names still don't resolve.

This is a Linux-side resolver problem, not a Windows problem. The same profile works on Windows because Windows integrates VPN DNS settings at the OS level automatically. Don't waste time comparing the two platforms.

Azure VPN DNS Linux Quick Fix

This is the fix that works for the majority of cases. It takes five to ten minutes. You're enabling systemd-resolved, relinking resolv.conf, and restarting NetworkManager. That's it.

1

Fix systemd-resolved and resolv.conf Easy

  1. Check if systemd-resolved is running
    Open a terminal and run:
    systemctl status systemd-resolved
    If it says 'inactive' or 'dead', continue to the next step. If it's active, skip to step 3.
  2. Enable and start systemd-resolved
    sudo systemctl enable systemd-resolved
    sudo systemctl start systemd-resolved
    You should see it flip to 'active (running)' when you check status again.
  3. Check what resolv.conf is pointing at
    ls -la /etc/resolv.conf
    If it's a regular file or symlinks to /run/systemd/resolve/resolv.conf, it needs changing. The correct target is /run/systemd/resolve/stub-resolv.conf.
  4. Relink resolv.conf to the stub resolver
    sudo mv /etc/resolv.conf /etc/resolv.conf.backup
    sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
    This tells the system to route all DNS through the systemd-resolved stub at 127.0.0.53.
  5. Restart NetworkManager
    sudo systemctl restart NetworkManager
    This forces NetworkManager to reload its DNS integration with systemd-resolved.
  6. Reconnect the Azure VPN client and test
    Open the Azure VPN client, connect your profile, and run:
    resolvectl status
    You should see the VPN-supplied DNS servers listed under the VPN interface. Try resolving a private hostname with dig internal.yourdomain.com.
Success: The 'Couldn't set DNS server/domains' error is gone and the VPN connects cleanly. resolvectl status shows DNS servers on the VPN interface.
If your distro uses resolvconf instead of systemd-resolved, you may need to install systemd-resolved explicitly. On Debian/Ubuntu: sudo apt install systemd-resolved. On Fedora/RHEL it's included by default.

Some setups need one extra step. If NetworkManager still isn't delegating DNS to systemd-resolved after the restart, check /etc/NetworkManager/NetworkManager.conf. Under the [main] section, dns should be set to systemd-resolved:

[main]
dns=systemd-resolved

Add that line if it's missing, save the file, and restart NetworkManager again. This is a less common issue but it does come up on custom installs and some enterprise Linux images.

Worth knowing: if you're managing a fleet of Linux clients and this keeps happening after OS updates, it's worth looking at whether your VPN management software handles resolver stack configuration automatically. A decent VPN client that's properly optimised for Linux will handle systemd-resolved integration without you having to babysit the symlink every time.

More Azure VPN DNS Linux Solutions: Profile and Azure-Side Fixes

The quick fix above sorts the Linux resolver stack. But there's a second class of problem: the VPN connects, systemd-resolved is happy, but private hostnames still don't resolve. That's a different issue entirely, and it's usually in the Azure VPN profile XML or the VNet DNS configuration.

2

Fix DNS Suffixes in the Azure VPN Profile XML Easy

  1. Download the current VPN client profile from Azure
    Go to the Azure portal, open your Virtual Network Gateway, click 'Point-to-site configuration', and download the VPN client. Extract the zip. You'll find an XML file inside the AzureVPN folder.
  2. Open the profile XML and check for dnssuffixes
    Open the XML in any text editor. Look for a <clientconfig> section. If there's no <dnssuffixes> block, the client won't know which domains to resolve over the tunnel.
  3. Add the required DNS suffix entries
    Add a block like this inside <clientconfig>:
    <dnssuffixes><dnssufix>corp.yourdomain.com</dnssufix></dnssuffixes>
    Add one <dnssufix> entry per internal domain. Yes, Microsoft's XML schema does spell it 'dnssufix' (one 'f'). Don't correct it or the client won't parse it.
  4. Re-import the modified profile
    In the Azure VPN client on Linux, remove the old profile and import the modified XML. Reconnect and test with nslookup internal.yourdomain.com.
Success: Private hostnames resolve correctly through the tunnel after reconnecting with the updated profile.

There's also the question of whether the DNS server listed in your Azure VNet configuration is actually reachable. Go to the Azure portal, open your Virtual Network, and check the DNS servers setting. If it's set to 'Azure-provided', that's the problem. Azure's internal DNS (168.63.129.16) is not reachable through Point-to-Site tunnels, as Microsoft's own documentation confirms. You need a custom DNS server IP there, pointing at a forwarder that's actually reachable over the tunnel.

If you've made any DNS changes on the Azure side (VNet DNS settings, gateway configuration, added or changed DNS servers), you must re-download the VPN client profile and re-import it. The profile packages up the gateway settings at the time of download. Stale profiles are a surprisingly common reason things stay broken after you've fixed the Azure side. And yes, this catches people out regularly, including experienced engineers who forget that step.

This is also a good moment to check whether your VPN policy routing is set up correctly. If you're running a more complex network where some traffic should go through the tunnel and some shouldn't, a misconfigured split-tunnel setup can cause DNS queries to miss the tunnel entirely. The concepts are similar to what's covered in ER605 VPN policy routing guides, where getting the route table right is just as important as the DNS config.

Advanced Azure VPN DNS Linux Fixes: DNS Forwarder Setup

This tier is for when the Linux client is fine, the profile has the right suffixes, but the DNS server itself is the problem. Either it's not reachable through the tunnel, it's not configured to handle private queries, or the network topology means Azure DNS simply won't work for your use case.

3

Deploy a Custom DNS Forwarder in Azure Advanced

  1. Deploy a DNS forwarder VM in your Azure VNet
    Spin up a small Linux VM (Ubuntu 22.04 works well) in the same VNet your VPN clients connect to. Install bind9 or dnsmasq. The VM needs a static private IP.
  2. Configure the forwarder to listen on its private IP
    Edit /etc/bind/named.conf.options (for bind9) and set listen-on { your.private.ip; };. Add allow-query { any; }; so VPN clients can reach it. For dnsmasq, set listen-address=your.private.ip in /etc/dnsmasq.conf.
  3. Set up conditional forwarders for private domains
    For bind9, add a zone block for each internal domain pointing at your on-premises or private DNS. For public names, forward to a reliable public resolver like 1.1.1.1 or 8.8.8.8. This way private names resolve internally and public names still work.
  4. Open UDP 53 in the Azure NSG
    In the Azure portal, find the NSG attached to the forwarder VM's subnet or NIC. Add an inbound rule allowing UDP port 53 from your VPN client address pool. Without this, DNS queries from VPN clients will be silently dropped.
  5. Update the VNet DNS settings to point at the forwarder
    In the Azure portal, go to your Virtual Network, DNS servers, and enter the forwarder VM's private IP. Save. This tells all resources in the VNet (including VPN clients) to use your forwarder.
  6. Rebuild and redeploy the VPN client profile
    Re-download the VPN client package from the Azure portal. The new profile will include the updated DNS server IP. Re-import on the Linux client, reconnect, and verify with dig @your.forwarder.ip internal.yourdomain.com.
Success: dig returns correct private IP addresses for internal hostnames. resolvectl status shows the forwarder IP under the VPN interface.
If your DNS forwarder is on a Linux VM, run netstat -uln | grep 53 to confirm it's actually listening on the right IP and port. A common gotcha is bind9 defaulting to listening only on localhost after install, which means VPN clients can never reach it even if the NSG is open.

If the environment uses Active Directory, the DNS setup gets a bit more involved. AD DNS needs to handle the private namespace, and your Azure forwarder needs conditional forwarders pointing at the AD DNS servers. The AD DNS servers need to be reachable from the forwarder VM, which means either they're in Azure or there's a working site-to-site VPN between Azure and on-premises. Don't try to shortcut this by pointing VPN clients directly at an on-premises AD DNS server. The routing usually isn't there for Point-to-Site clients, and you'll end up chasing a problem that looks like a DNS issue but is actually a routing issue.

One more thing worth checking if you're getting intermittent failures rather than total DNS failure: UDP packet fragmentation. DNS over UDP is limited to 512 bytes by default (EDNS0 extends this, but not all paths support it cleanly). If your VPN tunnel has a lower MTU than expected, large DNS responses can get fragmented and dropped. Test with dig +bufsize=512 internal.yourdomain.com and see if that's more reliable than normal queries. If it is, you've got an MTU problem, not a resolver problem.

For teams running a lot of Linux endpoints on Azure VPN, it's also worth noting that some productivity tools and large file workflows can behave oddly when DNS is partially broken. Things like trying to open large PDF files on Linux from a network share that resolves over the VPN will just hang silently if DNS is flaky, which makes the root cause harder to spot.

Preventing Azure VPN DNS Linux Problems

Most of these problems are repeat offenders. The same engineers hit them again six months later after an OS upgrade or a VNet change. Here's what actually prevents that:

Keep systemd-resolved healthy across updates. Some distro upgrades (particularly Ubuntu LTS point releases) can reset the resolv.conf symlink back to a static file. Add a quick check to your post-upgrade checklist: ls -la /etc/resolv.conf and confirm it still points at the stub resolver. Takes ten seconds.

Re-download the profile after every Azure DNS change. This is the one people forget most often. Change a DNS server IP in the VNet settings, forget to re-download the profile, spend an hour wondering why nothing works. The profile is a snapshot. It doesn't update itself.

Don't rely on Azure DNS for private names over Point-to-Site. It doesn't work. It's not a bug, it's by design. Deploy a forwarder and document its IP. Put the IP in your runbook. Put it in the VPN profile XML comments if you have to.

Test DNS immediately after any change. Run dig internal.yourdomain.com right after reconnecting. Don't wait until a user reports a problem. Catching a broken DNS suffix entry or an unreachable forwarder takes thirty seconds at connection time and thirty minutes of head-scratching two days later when someone can't reach a server.

Document your DNS suffix requirements. Every internal domain that needs to resolve over the VPN should be listed somewhere. The VPN profile XML, a wiki page, a README in the repo where you store the profile. Doesn't matter where, as long as it exists. When someone adds a new internal service six months from now, they'll know to add the suffix.

Azure VPN DNS Linux Summary

Azure VPN DNS Linux failures almost always come down to one of two things: the Linux resolver stack isn't set up for the Azure VPN client to talk to, or the Azure-side DNS configuration is incomplete. Fix systemd-resolved and the resolv.conf symlink first. That clears the error for the majority of cases. If private names still don't resolve after that, check the VPN profile XML for missing DNS suffixes and verify that the DNS server your VNet points at is actually reachable through the tunnel. For anything more complex, deploy a proper DNS forwarder in Azure with conditional forwarding, rebuild the profile, and test with dig. The Azure VPN DNS Linux problem is annoying but it's always fixable once you know which layer is broken.

Frequently Asked Questions

Windows has built-in DNS integration that handles VPN-supplied settings automatically. Linux requires systemd-resolved to be active and properly linked via resolv.conf. The Azure VPN client on Linux uses DBus to push DNS settings into systemd-resolved, and if that service is not running or resolv.conf points elsewhere, the push fails and you get the 'Couldn't set DNS server/domains' error.

It means the Azure VPN client tried to update DNS settings via systemd-resolved over DBus and got an error back. The most common causes are systemd-resolved not running, resolv.conf not pointing to the stub resolver, or NetworkManager not delegating DNS to systemd-resolved.

Only if the quick fix gets you connected but private names still fail to resolve. In that case you need to add dnssuffixes entries to the profile XML so the client knows which internal domains to route through the VPN tunnel. It's a one-time change per environment.

The Azure VPN client on Linux specifically targets systemd-resolved via DBus. Alternative resolvers will produce the same error unless you configure them to sit behind the systemd-resolved stub interface. It's much less hassle to just enable systemd-resolved and let it handle delegation.

Azure's internal DNS address 168.63.129.16 is not routable through Point-to-Site VPN tunnels. You must deploy a custom DNS forwarder on a VM inside your Azure VNet, configure it to forward private domain queries internally and recurse externally for public names, then point your VNet DNS settings at that forwarder's private IP.