Configuring Linux DNS
There are an incredible number of ways to configure DNS on Linux.
Tailscale attempts to interoperate with any Linux DNS configuration it finds already present. Unfortunately, some are not entirely amenable to cooperatively managing the host's DNS configuration.
Common problems
NetworkManager + systemd-resolved
If you're using both NetworkManager and systemd-resolved (as in
common in many distros), you'll want to make sure that
/etc/resolv.conf is a symlink to
/run/systemd/resolve/stub-resolv.conf. That should be the
default. If not,
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
When NetworkManager sees that symlink is present, its default behavior is to use systemd-resolved and not take over the resolv.conf file.
After fixing, restart everything:
sudo systemctl restart systemd-resolved
sudo systemctl restart NetworkManager
sudo systemctl restart tailscaled
systemd-resolved: Override DNS servers does not cover DHCP search domains
On a host that uses systemd-resolved, enabling Override DNS servers in the admin console does not redirect every query to the tailnet nameservers. Two kinds of names still go to the DNS server that another interface received from DHCP:
- Names under a search domain that the other interface received from DHCP. Examples are
printer.attlocal.neton a home network andip-10-0-0-5.us-west-2.compute.internalon an EC2 instance. - Bare single-label names, such as
myhostinssh myhost.systemd-resolvednever sends a single-label name upstream as is. It expands the name with the search domains of every interface first, in an order Tailscale does not control, and the DHCP domain often sorts ahead of the tailnet's.ts.netdomain. Home gateways commonly answermyhost.attlocal.netwith the LAN address of that host, so the MagicDNS name is never tried.
The cause is how systemd-resolved routes queries. With the override enabled, tailscaled gives the tailscale0 link the nameserver 100.100.100.100, the tailnet search domain, the catch-all routing domain ~., and the default route. That is the strongest configuration systemd-resolved offers for one link. systemd-resolved still sends each query to the link whose domain matches the most labels of the name. The catch-all domain ~. matches zero labels, so a DHCP domain such as attlocal.net wins for every name under it. Every other name routes through tailscale0 as expected.
To confirm this is the problem, compare the links:
resolvectl status
With the override enabled, the tailscale0 link lists 100.100.100.100 under DNS Servers and lists your tailnet domain and ~. under DNS Domain. If another link lists a domain under DNS Domain, names under that domain go to that link's DNS server.
To fix this, stop the DHCP client from installing the search domain on the other interface.
On a host that uses netplan, add dhcp4-overrides under the interface in your netplan file in /etc/netplan/, then run sudo netplan apply. Add the same setting under dhcp6-overrides if the interface also uses DHCPv6.
network:
version: 2
ethernets:
enp1s0:
dhcp4: true
dhcp4-overrides:
use-domains: false
On a host that uses NetworkManager, set ipv4.ignore-auto-dns on the connection, then reactivate the connection. Replace <connection-name> with the connection name from nmcli connection show. This setting also drops the DHCP nameservers from the connection. That is fine while the override is enabled, because the tailnet nameservers handle every query.
sudo nmcli connection modify "<connection-name>" ipv4.ignore-auto-dns yes
sudo nmcli connection up "<connection-name>"
To clear the domain once without changing any configuration file, run sudo resolvectl domain enp1s0 '' with the name of the DHCP interface. The DHCP client installs the domain again at the next lease renewal.
If you only need tailnet names to work, use the fully qualified MagicDNS name, such as myhost.tailnet-name.ts.net, instead of the bare name.
DHCP dhclient overwriting /etc/resolv.conf
Without any DNS management system installed, DHCP clients like
dhclient and programs like tailscaled have no other options than
rewriting the /etc/resolv.conf file themselves, which results in
them sometimes fighting with each other. (For instance, a DHCP renewal
rewriting the resolv.conf resulting in loss of MagicDNS functionality.)
Possible workarounds are to use resolvconf or systemd-resolved.
Issue 2334 tracks making Tailscale react to other
programs updating resolv.conf so Tailscale can add itself back.
DNS issues with Amazon Linux
On Amazon Linux, Tailscale's DNS can break due to an infinite forwarding loop. When Tailscale backs up and replaces /etc/resolv.conf with its own DNS server (100.100.100.100), systemd-resolved adds that address to the backup file. Later, when Tailscale re-reads the backup to find upstream DNS servers, it forwards queries to itself, creating a loop that breaks DNS resolution. This is especially known to occur on Amazon Linux 2023.
A workaround to this issue is to reconfigure systemd-resolved from Amazon's legacy mode to stub resolver mode by masking Amazon's custom configuration and pointing /etc/resolv.conf to the stub resolver.
mkdir -p /etc/systemd/resolved.conf.d
ln -sf /dev/null /etc/systemd/resolved.conf.d/resolved-disable-stub-listener.conf
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
openresolv with no registered interfaces (FreeBSD static networking)
Tailscale uses openresolv to manage DNS when /etc/resolv.conf starts with the line # Generated by resolvconf. In that mode, Tailscale learns the system's DNS servers from the per-interface entries that programs register with resolvconf -a. A DHCP client registers an entry for each interface it configures. On a FreeBSD host with static network configuration, nothing calls resolvconf -a, so openresolv has no registered interfaces. DNS servers listed in /etc/resolvconf.conf with name_servers or name_servers_append are not registered interfaces, so Tailscale cannot read them.
On Tailscale v1.106 or later, a host in this state shows this warning and Tailscale leaves /etc/resolv.conf alone:
Your device has no system DNS servers for Tailscale to forward queries to, so Tailscale has left DNS alone. MagicDNS stays inactive until the system has DNS servers of its own.
On versions earlier than Tailscale v1.106, the same host shows this error instead:
Tailscale failed to fetch the DNS configuration of your device: exit status 1
To fix this, register the static DNS servers with openresolv before tailscaled starts. Do not use tailscale as the interface name.
To check whether this is the problem, register the servers once by hand and restart Tailscale. Replace <interface> with the name of your network interface and <dns-server> with the IP address of your DNS server.
printf 'nameserver <dns-server>\n' | resolvconf -a <interface>
resolvconf -i
service tailscaled restart
The resolvconf -i command should list <interface>.
To make the registration persistent, add an rc.d script that runs before tailscaled. Save the following as /usr/local/etc/rc.d/resolvconf_static and make it executable.
#!/bin/sh
# PROVIDE: resolvconf_static
# REQUIRE: NETWORKING
# BEFORE: tailscaled
. /etc/rc.subr
name="resolvconf_static"
rcvar="resolvconf_static_enable"
load_rc_config $name
: ${resolvconf_static_enable:=no}
: ${resolvconf_static_interface:=""}
start_cmd="${name}_start"
resolvconf_static_start()
{
/sbin/resolvconf -a "${resolvconf_static_interface}" \
< "/etc/resolv_${resolvconf_static_interface}.conf"
}
run_rc_command "$1"
Enable the script in /etc/rc.conf. Set resolvconf_static_interface to the same interface name you used in the check above.
resolvconf_static_enable="YES"
resolvconf_static_interface="<interface>"
The script reads its DNS settings from /etc/resolv_<interface>.conf, where <interface> is the interface name from /etc/rc.conf. For example, if the interface is em0, the script reads /etc/resolv_em0.conf. Create that file with ordinary resolv.conf lines, such as nameserver and search.
Do not fix this by moving the DNS servers into name_servers in /etc/resolvconf.conf. That key places the servers ahead of Tailscale's resolver in /etc/resolv.conf, so lookups for tailnet names go to the static server and fail. The name_servers_append key orders correctly, but Tailscale still cannot read it, so MagicDNS stays inactive.
This applies to both openresolv versions found in FreeBSD: 3.9.2, which every FreeBSD release up to and including 15.0 ships in the base system, and 3.17.4, which the stable/14 branch imported in July 2026.