A stray systemd-resolved restart can wipe out DNS settings you set by hand, so put them in a drop-in file instead. You will create a local systemd-resolved drop-in, set explicit DNS servers, and confirm which configuration the resolver is using. The same workflow applies to search domains, DNSSEC, DNS-over-TLS, caching and the local stub listener. Allow about 10 minutes, including a connectivity check.
This guide matches the installed systemd-resolved package, version 255.4-1ubuntu8.17, whose manpage identifies the format as systemd 255. You need root access and an active systemd-resolved service. The examples use documentation addresses, so replace them with DNS servers supplied by your network administrator or provider.
First record the current state. This command is ordinary, read-only work:
resolvectl status
Look for the current DNS servers, per-link settings and the resolv.conf mode. Save the output if you may need to compare or recover later.
Use a file below /etc/systemd/resolved.conf.d/. Files in this directory override the main configuration and are read in lexicographic filename order. A two-digit prefix makes the intended priority visible. Creating this file needs elevated privileges:
sudo install -d -m 0755 /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/50-local-dns.conf >/dev/null <<'EOF'
[Resolve]
DNS=192.0.2.53 2001:db8::53
Domains=~example.internal example.internal
DNSSEC=allow-downgrade
DNSOverTLS=no
EOF
The addresses above are reserved documentation addresses and will not resolve names. Substitute real addresses before applying this to a working machine. The two entries in Domains= demonstrate different jobs: example.internal is a search suffix for single-label names, while ~example.internal is a route-only domain for directing matching queries to suitable per-link DNS servers. A route-only domain has no effect unless per-link DNS servers are known.
DNSSEC=allow-downgrade attempts validation but can disable it when the server cannot support it. Use DNSSEC=yes only when your DNS service supports DNSSEC correctly and your trust-anchor and system updates are maintained. DNSOverTLS=no is explicit here, not a claim that ordinary DNS is private. Setting it to opportunistic permits fallback and does not authenticate the server; setting it to yes requires a DNS-over-TLS server with a valid certificate. If you use encrypted DNS, specify a server name in DNS=, such as 192.0.2.53#dns.example, when that name is the certificate identity.
Before restarting anything, ask systemd to display the main file and drop-ins as one configuration. This is read-only:
systemd-analyze cat-config systemd/resolved.conf
Confirm that your file appears under /etc/systemd/resolved.conf.d/ and that the final value for each single-value option is the one you expect. Drop-ins are sorted by filename across their configuration directories. For a single-value option, the last assignment wins. List-valued options can accumulate entries, so do not assume that adding a second file removes an earlier list.
A vendor drop-in in /usr/lib/systemd/resolved.conf.d/ can still affect the result. The local /etc directory has higher precedence. To disable one vendor file, the manpage recommends a same-named symlink to /dev/null in the local directory. Do that only after identifying the exact filename, because it is a deliberate package override.
systemd-resolved cannot reload this configuration in place on the installed system, so restarting it is service-disrupting. Existing lookups may briefly fail. Schedule this for a suitable moment and keep a second shell or console available:
sudo systemctl restart systemd-resolved
resolvectl status
Check that the global and link sections show the expected protocols and DNS servers. Then test a name that should be available through the configured service:
resolvectl query example.com
The command should return an answer rather than a resolver error. A successful query alone does not prove DNSSEC validation or DNS-over-TLS authentication. Use resolvectl status to check the resolver's reported protocol state, and test an internal name separately if you configured a search or route-only domain.
An empty DNS= setting does not necessarily mean that no DNS servers are used. When it is not specified, resolved can use servers in /etc/resolv.conf; per-link servers supplied by network configuration and runtime applications also matter. FallbackDNS= is only used when no other DNS information is known, and an omitted value uses a compiled-in list.
Do not enable ResolveUnicastSingleLabel=yes casually. It forwards single-label names to global DNS servers even without search domains, which can disclose internal-looking names to servers outside your control. Also remember that LLMNR= and MulticastDNS= require the corresponding per-link setting as well as the global setting.
If name resolution breaks, undo the local file and restart the service. This removes only the file created in this guide:
sudo rm /etc/systemd/resolved.conf.d/50-local-dns.conf
sudo systemctl restart systemd-resolved
resolvectl status
The removal is reversible only if you kept the file contents, so copy the file to a protected note before editing it. Do not delete other files from the directory while troubleshooting.
/etc/systemd/resolved.conf.d/.systemd-analyze cat-config systemd/resolved.conf shows the expected merged values and precedence.resolvectl status reports the intended DNS state after the restart.