You rebooted and DNS broke
You rebooted after an update and your browser hangs on DNS_PROBE_FINISHED_BAD_CONFIG. Or you plugged into a new Wi-Fi network and the terminal refuses to resolve hostnames. You check /etc/resolv.conf and see nameserver 127.0.0.53. You think the system is pointing to itself and breaking the internet. It isn't. That address is the local stub resolver, and it's working exactly as designed. The problem is usually a misconfiguration upstream or a stale cache, not the resolver itself.
What systemd-resolved actually does
systemd-resolved acts as a local proxy for DNS queries. Instead of every application asking your router or ISP for domain names, they ask the local machine at 127.0.0.53. The resolver caches the answers, validates DNSSEC signatures if enabled, and forwards the request to the real DNS servers provided by your network.
Think of it like a receptionist in a large office. Employees don't call external departments directly. They ask the receptionist. The receptionist checks a sticky note on the desk (the cache) before making the call. If the note is missing, the receptionist dials the number, writes the result down, and hands it back. This speeds up lookups and keeps the network traffic tidy.
The address 127.0.0.53 is a loopback address. Queries sent here never leave your machine. The resolver daemon listens on this address and forwards the request to the real DNS servers. This design prevents DNS leaks and allows the system to cache responses locally. If the resolver crashes, applications fail fast rather than hanging indefinitely. The loopback design is intentional and secure.
Ensure the service is running
Verify the service is active and enabled. The resolver must be running for the stub address to respond.
sudo systemctl enable --now systemd-resolved
# enable ensures the service starts on boot.
# --now starts the service immediately without a reboot.
Check the status to confirm the daemon is healthy.
systemctl status systemd-resolved
# Check the active state. Look for "active (running)" in green.
# If the service is inactive, the stub resolver at 127.0.0.53 won't answer queries.
# Read the log lines below the status for the reason if it failed to start.
Check status before restart. A restart won't fix a service that failed to start due to a config error.
Verify the resolv.conf symlink
Fedora's NetworkManager manages /etc/resolv.conf. The file should be a symlink, not a static file. If you edited the file directly, NetworkManager will overwrite your changes on the next connection change. Always manage symlinks in /etc, never edit files in /usr/lib. Files in /usr/lib ship with packages and get overwritten on updates.
Confirm the resolver configuration points to the stub file.
ls -la /etc/resolv.conf
# Verify the symlink target. It must point to ../run/systemd/resolve/stub-resolv.conf.
# A static file here breaks dynamic DNS updates from NetworkManager.
# If the output shows a regular file, the symlink is broken.
Restore the symlink if it is missing or points to the wrong target.
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# Restore the symlink. The -f flag forces overwrite if a broken link exists.
# This ensures applications query the local stub resolver instead of a hardcoded server.
# NetworkManager will now update the stub file automatically when connections change.
Trust the symlink. Manual edits to resolv.conf drift and vanish on reboot.
Configure global DNS and DNSSEC
Configure fallback servers and DNSSEC in the main configuration file. This sets the baseline behavior when the network provides no DNS data.
[Resolve]
# DNS= sets the default servers used when the network provides none.
# List multiple servers separated by spaces for redundancy.
DNS=1.1.1.1 8.8.8.8
# FallbackDNS= activates only if all DNS= servers fail to respond.
# Use this for a last-resort rescue path, not for load balancing.
FallbackDNS=9.9.9.9
# DNSSEC= enables signature validation. Use "yes" for strict validation.
# "allow-downgrade" is safer for mixed networks but less secure.
# Strict mode blocks queries if the signature is missing or invalid.
DNSSEC=yes
# Cache= stores recent lookups to speed up repeated queries.
Cache=yes
Restart the service to apply the configuration.
sudo systemctl restart systemd-resolved
# Restart the service to load the new configuration.
# The cache is cleared automatically on restart.
# The resolver does not hot-reload configuration files.
Restart the service after config changes. The resolver does not hot-reload configuration files.
Override DNS per connection
NetworkManager pushes DNS settings per interface. You can override DHCP settings for a specific connection to force custom servers.
Override DNS settings for a specific network connection.
sudo nmcli connection modify "MyWiFi" ipv4.dns "1.1.1.1 8.8.8.8"
# Set custom DNS servers for the connection profile.
# This overrides the DNS servers received via DHCP.
sudo nmcli connection modify "MyWiFi" ipv4.ignore-auto-dns yes
# Disable automatic DNS configuration from the network.
# Without this flag, DHCP servers may still append their own DNS entries.
sudo nmcli connection up "MyWiFi"
# Reactivate the connection to apply the changes immediately.
# The resolver picks up the new settings from NetworkManager.
Changes made with nmcli connection modify are persistent. They survive reboots and connection drops. This differs from runtime commands that only apply until the next reboot. When you modify a connection profile, you are editing the configuration stored in /etc/NetworkManager/system-connections/. The nmcli connection up command reloads the profile and applies the changes to the running system.
Reactivate the connection after modifying nmcli settings. Changes don't apply to an active link until you bring it up again.
Inspect state and verify resolution
Inspect the active DNS state and cache statistics. This shows exactly which servers are in use and whether DNSSEC is validating.
resolvectl status
# Display the current resolver state for all interfaces.
# Check the "DNS Servers" line to confirm which upstream servers are active.
# Look for "DNSSEC" to verify validation status per interface.
# The "Current Scopes" line shows which interface provides the default route.
The output of resolvectl status contains several sections. The "Global" section shows fallback servers and DNSSEC settings. The per-interface sections show the active DNS servers and the "DNSSEC" status for that link. If you see "DNSSEC: no" on an interface, the resolver is not validating signatures for traffic on that link. This can happen if the upstream server doesn't support DNSSEC or if the interface is configured to bypass validation.
Test resolution and flush the cache if needed.
resolvectl query fedoraproject.org
# Perform a DNS lookup using the local resolver.
# This command shows the answer and the server that provided it.
# Use this instead of nslookup to see resolver-specific metadata.
sudo resolvectl flush-caches
# Clear the local cache to force fresh lookups.
# Use this when a domain's IP changes but your system still resolves the old address.
# Flushing the cache is safe and does not break active connections.
Run resolvectl query first. It shows exactly which server answered, which saves time debugging upstream issues.
Common pitfalls and error patterns
If you see Temporary failure in name resolution in the terminal, the resolver cannot reach any upstream server. This usually means the network interface has no DNS configuration, or the firewall is blocking outbound UDP port 53. Check resolvectl status to see if any DNS servers are listed. If the list is empty, NetworkManager hasn't received DNS data from the DHCP server.
On slow networks, DHCP may take several seconds to provide DNS servers. During this window, systemd-resolved has no upstream servers and queries will fail. This is normal behavior. The resolver waits for NetworkManager to report the DNS configuration. If you see transient failures immediately after connecting, wait for the DHCP lease to complete. You can monitor this with journalctl -fu NetworkManager. The log will show "DHCP4 address" and "DNS" entries appearing sequentially.
The error DNSSEC validation failed means the resolver detected a signature mismatch. This can happen if your upstream DNS server is misconfigured or if a man-in-the-middle attack is occurring. Do not disable DNSSEC to fix this. Investigate the upstream server. If you are on a public Wi-Fi that intercepts DNS, use DNSSEC=allow-downgrade in the config, but understand you are lowering security.
Some applications ignore the system resolver and contact DNS servers directly. This breaks DNSSEC validation and cache benefits. If resolvectl query works but an application fails to resolve, the application might be bypassing the stub. Check the application's configuration for a custom DNS setting. If the application has no configuration option, use strace to verify it is connecting to 127.0.0.53. If it connects to an external IP, the application is hardcoded to use a specific resolver.
SELinux denials rarely block systemd-resolved itself, but they can block applications from writing to DNS-related sockets. If an app fails to resolve, check journalctl -t setroubleshoot for one-line summaries. Read the denial before disabling SELinux. Most resolution issues are network config, not security policy. When debugging, use journalctl -xeu systemd-resolved. The -x flag adds explanatory text to error codes, and -e jumps to the end of the log. Most sysadmins type this muscle-memory style. Reading the raw journal without -x often leaves you staring at cryptic error codes without context.
Read the journal before guessing. journalctl -xeu systemd-resolved shows the exact reason the service failed or dropped a query.
When to use this vs alternatives
Use systemd-resolved when you want a unified local cache and DNSSEC validation across all interfaces. Use NetworkManager to manage per-connection DNS settings and let the resolver handle the forwarding. Use resolvectl to inspect state and flush caches instead of editing config files manually. Use dnf install bind when you need to run a full authoritative DNS server, not just a client resolver. Stay on the default stub resolver unless you have a specific requirement for a different caching daemon.