Home / Alt manpages / resolv.conf(5)

  • resolv.conf(5)
  • File format
  • linux

Tune DNS Lookups Safely with resolv.conf

You edited /etc/resolv.conf, DNS worked, and an hour later your change had vanished; that file often belongs to someone else. You will find out who owns it, understand the settings that shape ordinary lookups and change it only when this machine really owns it. Allow about 15 minutes.

  • You need: a shell and the installed resolv.conf(5) manpage.
  • Administrator access: only if you are changing a system-managed file.

1. Check which file you are really using

/etc/resolv.conf is the conventional path, but it is often a symbolic link generated by NetworkManager, systemd-resolved, a container runtime or another network manager. Look before you touch:

$ ls -l /etc/resolv.conf
$ readlink -f /etc/resolv.conf
$ sed -n '1,80p' /etc/resolv.conf

On the machine used for this guide, the link points into /run/systemd/resolve and the file says it is dynamic. Editing it directly would be temporary at best and could fight the service that owns it, so change that manager's settings instead.

Warning

Do not replace a symbolic link with a regular file until you have identified the manager and planned a rollback.

Checkpoint

Record the output of readlink -f. Under /run means generated. If ls -l shows a regular file, carry on, but still check whether a package or service rewrites it.

2. Read the current settings

The file is line-oriented. A keyword starts the line, followed by whitespace and its value. Lines starting with # or ; are comments. These are the settings that affect most hosts:

nameserver 192.0.2.53
nameserver 2001:db8::53
search office.example.test dev.example.test
options ndots:1 timeout:2 attempts:2 rotate

Those addresses are documentation placeholders, not usable DNS servers.

  • nameserver takes an IPv4 or IPv6 address, up to three entries. With none at all, the resolver falls back to the local machine.
  • Order matters. Multiple servers are tried in order when a query times out.
  • rotate spreads queries across the listed servers instead of always starting with the first.
  • search applies to names with fewer dots than the ndots threshold. With the default ndots:1, a name containing a dot is tried as an absolute name first; a bare name like printer can then be tried with each suffix.
  • Keep the search list short. Long or remote lists add traffic and delay, so include only domains you actually use.
  • Last search line wins if there are several. The older domain keyword handles one search entry and is obsolete.

3. Choose timeout and retry values deliberately

The main numeric controls are timeout:n and attempts:n. On this glibc 2.39 system the documented defaults are five seconds and two attempts, and the resolver silently caps them at 30 seconds and five attempts.

They are per-resolver controls, not a promise that one application call finishes within timeout seconds: a single call can query several servers and do more than one lookup.

Example

This small, explicit setting makes a workstation fail faster when its DNS service is down.

options timeout:2 attempts:2
  • Do not hide a flaky network behind a tiny timeout. It turns brief packet loss into application failures.
  • Keep ndots low unless you have a specific internal naming scheme. A high value can make a short name generate many search-domain queries before it is tried as an absolute name.

Checkpoint

Write down the current nameserver, search and options lines before changing anything. That is your quickest recovery reference.

4. Test overrides on one process first

glibc lets a process override the search list with LOCALDOMAIN and amend options with RES_OPTIONS. It is a safe way to try option syntax on one command without touching the system file or any other process:

$ RES_OPTIONS='ndots:2 timeout:1 attempts:1' getent hosts localhost
::1             localhost
$ printf 'exit status: %s\n' "$?"
exit status: 0

Your address may differ. You want exit status zero and a usable localhost entry.

Tip

getent exercises the host lookup path configured by NSS, so it is a practical smoke test, not a packet-level DNS trace. A localhost answer may come from /etc/hosts, so it does not prove an external nameserver is reachable.

To test a search-list override, use a name that should exist in your own DNS domain, not an invented public one:

$ LOCALDOMAIN='YOUR.INTERNAL.DOMAIN' RES_OPTIONS='ndots:2 timeout:2 attempts:1' getent hosts HOSTNAME

Replace both uppercase values with approved internal ones. The variables disappear when the command exits.

Warning

Do not put secrets in these variables, and do not paste an untrusted string into a shell command.

5. Change a static file only with a rollback

Warning

Changing resolver settings can break package downloads, SSH name lookups, monitoring and services. Do it in a maintenance window with an existing shell kept open. If /etc/resolv.conf is a symlink or managed by a service, stop here and change the manager's configuration instead.

For a confirmed static regular file, take a backup, edit with elevated privileges and keep the content minimal:

$ sudo cp --preserve=mode,ownership,timestamps /etc/resolv.conf /etc/resolv.conf.before-dns-change
$ sudoedit /etc/resolv.conf

A typical static file looks like this, using real DNS servers from your network administrator:

nameserver DNS_SERVER_1
nameserver DNS_SERVER_2
search YOUR.INTERNAL.DOMAIN
options timeout:2 attempts:2
  • Replace every placeholder. Do not copy the documentation addresses from this guide.
  • One line each. Keep each keyword and its value on a single line.
  • No familiar-looking suffixes. A search suffix changes where short names are sent, so add one only on purpose.

Undo by restoring the backup, then verify again:

$ sudo cp --preserve=mode,ownership,timestamps /etc/resolv.conf.before-dns-change /etc/resolv.conf
$ sed -n '1,80p' /etc/resolv.conf

Recovery

The backup stays until you remove it. Do not delete it mid-incident; first prove normal lookups work and nothing is rewriting the file.

6. Verify and diagnose

Read the file again, then test a local entry and a name your DNS service should answer:

$ sed -n '1,80p' /etc/resolv.conf
$ getent hosts localhost
$ getent hosts HOSTNAME.YOUR.INTERNAL.DOMAIN
$ printf 'last status: %s\n' "$?"
  • Non-zero final status: the name was not resolved through the configured NSS path. Check spelling, server addresses, search suffix and network reachability.
  • File has reverted: a manager owns the configuration and will overwrite manual edits.
  • Lookups are slow: inspect the search list and ndots before shrinking timeouts.

Common traps

  • no-aaaa is not an IPv6 fix. It exists in glibc since 2.36 (so in the installed 2.39) as a diagnostic switch. It suppresses DNS AAAA queries, is incompatible with EDNS0 usage and DNSSEC validation by applications, and does not remove IPv6 data from /etc/hosts. Use it only for a controlled investigation with a clear removal plan.
  • trust-ad is security-sensitive. Since glibc 2.31 it lets the stub resolver request and preserve the DNSSEC AD bit, but you must trust both the validating resolver and the network path to it. Do not enable it just because a tutorial or copied configuration has it.

Done means

  • Owner known: you know whether /etc/resolv.conf is static or managed.
  • Settings understood: you can explain the active nameserver, search and options lines.
  • Tested small first: you tried resolver options per process before any system-wide edit.
  • Rollback ready: any static-file change has a dated backup and a tested restore command.
  • Lookups work: getent resolves a local name and an approved DNS name after the change.
  • Risky options off: diagnostic and trust-sensitive options stay disabled unless you have a documented reason.