Edit /etc/resolv.conf directly on a system running systemd-resolved and your change vanishes at the next boot: that file is generated. This guide identifies the resolver actually handling lookups, sets explicit DNS servers in a local drop-in, and proves the running service is using the result. Allow about 10 minutes. The examples target the systemd 255 behaviour documented by the Ubuntu package systemd-resolved 255.4-1ubuntu8.17.
You need a shell, an active network connection, and sudo access. Use two DNS server addresses supplied by your network administrator. The addresses in the examples are documentation placeholders, not servers you should copy blindly. Expect a brief interruption to name resolution when the service is restarted.
These instructions change only a file under /etc/systemd/resolved.conf.d/. Do not edit /run/systemd/resolve/stub-resolv.conf: systemd-resolved maintains that file. The service normally exposes its full resolver at 127.0.0.53, and the recommended compatibility arrangement is for /etc/resolv.conf to point to that generated stub file.
Start with read-only checks. They show whether the service is running, which interfaces have DNS scopes, and whether local applications are directed at the stub.
systemctl is-enabled systemd-resolved.service
systemctl is-active systemd-resolved.service
resolvectl status
readlink -f /etc/resolv.conf
resolvectl query example.org
A healthy result includes active, a Global or link-specific DNS scope, and a successful answer for example.org. The resolved path is commonly /run/systemd/resolve/stub-resolv.conf. If the service is inactive, fix that separately before changing configuration:
sudo systemctl start systemd-resolved.service
Checkpoint: Do not continue until you can tell which command currently supplies DNS servers. DHCP, per-link network configuration, resolvectl, and /etc/resolv.conf can all contribute settings.
Drop-ins are easier to audit and survive package updates better than edits to a vendor file. Files in /etc/systemd/resolved.conf.d/ take precedence over vendor configuration, and are applied in lexicographic filename order. Create one clearly named file with a late-enough prefix:
sudo install -d -m 0755 /etc/systemd/resolved.conf.d
sudo tee /etc/systemd/resolved.conf.d/90-local-dns.conf >/dev/null <<'EOF'
[Resolve]
DNS=192.0.2.53 2001:db8::53
Domains=~.
DNSSEC=allow-downgrade
DNSOverTLS=no
EOF
Replace both documentation addresses. DNS= sets global servers; per-link servers learned from network configuration can still participate. Domains=~. is a route-only root domain: it prefers these global servers for names that do not match a more specific routing domain. It is not a search suffix, so it does not turn printer into printer.example.
DNSSEC=allow-downgrade attempts validation but can fall back when the upstream cannot support it. Set DNSSEC=yes only when you know the configured servers support DNSSEC correctly and the host receives regular trust-anchor updates. DNSOverTLS=no makes the transport choice explicit; opportunistic TLS does not authenticate the server and strict TLS will make all lookups fail if the server or certificate is unsuitable.
The setting DNS= accepts IPv4 or IPv6 addresses, with optional ports, interface names, and certificate names. For a DNS-over-TLS server whose certificate name is not its address, the documented form is like 203.0.113.53#dns.example. Do not add that suffix unless you are also configuring and verifying TLS.
Restarting the service is a privileged, service-disrupting action. Save the file first, and keep another shell available if this is a remote machine.
sudo systemctl restart systemd-resolved.service
systemctl is-active systemd-resolved.service
resolvectl status
The status output should show the service as active and list the replacement servers. It may also show per-link servers: global DNS= does not erase information supplied by DHCP or another network manager. If the output still reflects an old configuration, check for a later drop-in with a conflicting option:
ls -la /usr/lib/systemd/resolved.conf.d /usr/local/lib/systemd/resolved.conf.d /etc/systemd/resolved.conf.d 2>/dev/null
grep -R --line-number --fixed-strings 'DNS=' /usr/lib/systemd/resolved.conf.d /usr/local/lib/systemd/resolved.conf.d /etc/systemd/resolved.conf.d 2>/dev/null
Use resolvectl query rather than assuming that a changed file proves the result. Test a public name, a local synthetic name, and a name in any private zone you deliberately configured.
resolvectl query example.org
resolvectl query localhost
resolvectl flush-caches
resolvectl query example.org
localhost is answered locally and does not prove that an upstream server works. The public query should return one or more addresses. Flushing caches is normally unnecessary because network changes flush them automatically, but the command is useful while testing. For a more detailed service-level view, inspect recent messages:
sudo journalctl -u systemd-resolved.service -b --no-pager -n 80
Remember that a single-label name is not normally sent to global unicast DNS. It needs a search domain, or the explicit ResolveUnicastSingleLabel=yes setting. Enabling that option can disclose internal-looking names to DNS servers outside your control, so prefer a correctly scoped search domain.
First distinguish a bad resolver configuration from a broken link:
systemctl is-active systemd-resolved.service
resolvectl status
resolvectl query localhost
resolvectl query example.org
If localhost works but the public query fails, check the server addresses, routing, firewall rules, DNSSEC mode, and any conflicting drop-ins. Strict DNSSEC can reject every answer from a server that does not support it correctly. Strict DNS-over-TLS can do the same when the certificate or server name is wrong.
To undo this guide's change, remove only the file created above and restart the service. This is destructive to that one configuration file, so confirm the path before pressing Enter:
sudo rm -- /etc/systemd/resolved.conf.d/90-local-dns.conf
sudo systemctl restart systemd-resolved.service
resolvectl status
After removal, the resolver returns to the remaining configuration sources. If the old settings do not return, inspect the drop-in directories and the network manager that supplies per-link DNS data. Do not replace /etc/resolv.conf with a hand-written file until you understand which component owns it.
systemctl is-active systemd-resolved.service reports active.resolvectl status shows the intended DNS servers and expected routing scope.resolvectl query example.org returns an answer after the change./etc/resolv.conf still points to the resolver arrangement you chose, rather than an accidentally edited generated file.90-local-dns.conf.