DNS Troubleshooting

This guide helps you diagnose and resolve common DNS issues in NetBird. Follow the structured approach below to identify and fix problems quickly.

Quick Diagnostics Checklist

Before diving deep, run through this quick checklist:

# 1. Is NetBird connected?
netbird status -d

# 2. Is the peer receiving the correct nameservers for match domains?
netbird status | grep -A 5 Nameserver

# 3. Check what DNS servers are currently active on the system
# Linux:
cat /etc/resolv.conf
resolvectl status 2>/dev/null || systemd-resolve --status 2>/dev/null
# macOS:
cat /etc/resolv.conf
scutil --dns
# Windows:
Get-DnsClientServerAddress

# 4. Verify the match domain nameserver is reachable from this peer
ping 10.0.0.53
# Replace with your nameserver IP

# 5. Test resolution directly against the match domain nameserver (bypass system resolver)
dig @10.0.0.53 app.internal.company.com
# Replace 10.0.0.53 with your actual nameserver IP

# 6. Can you resolve match domains through the system resolver?
# Linux:
resolvectl query app.internal.company.com
# macOS:
dscacheutil -q host -a name app.internal.company.com
# Windows/Cross-platform:
nslookup app.internal.company.com

# 7. Confirm public domains still resolve (verifies split DNS is working)
nslookup google.com

If any of these fail, continue to the relevant section below.

Common Issues and Solutions

Issue 1: Can't Resolve Internal Domains

Symptoms:

  • nslookup internal.company.internal fails
  • ping server.company.internal returns "unknown host"
  • Public domains work fine

Solutions:

Solution A: System Not Using NetBird DNS

The OS isn't configured to use NetBird's resolver.

Check: Refer to the Verifying Configuration section to confirm if your OS is using NetBird's resolver.

Fix: If the configuration is incorrect, restart NetBird to force the OS to pick up the DNS settings:

Linux/macOS:

sudo systemctl restart netbird
# or
sudo netbird down && sudo netbird up

Windows:

Restart-Service netbird

Solution B: Wrong Nameserver Configuration

NetBird is routing queries to the wrong DNS server.

  1. Go to Dashboard → DNS → Nameservers
  2. Check nameserver IPs:
    • Are they correct?
    • Are they reachable from peers?
  3. Check distribution groups:
    • Is the peer's group assigned to this nameserver?

Common mistakes:

// ❌ Wrong: Wildcard syntax not supported
{
  "domains": ["*.company.internal"]
}

// ✅ Correct: Single domain (automatically matches all subdomains)
{
  "domains": ["company.internal"]
}
// This matches company.internal, app.company.internal, server.company.internal, etc.

Solution C: Nameserver Unreachable

The configured nameserver can't be reached.

Test connectivity:

# Can peer reach the nameserver?
ping 10.0.0.1  # Replace with your nameserver IP

# Test DNS query directly
dig @10.0.0.1 internal.company.internal

# If this times out:
# → Firewall or routing issue
# → Check NetBird routes
# → Check firewall rules on DNS server

Issue 2: Public Domains Not Resolving

Symptoms:

  • Can't resolve google.com, github.com, etc.
  • Internal domains may work
  • "DNS resolution failed" errors

Diagnosis:

Refer to Step 7 in the Quick Diagnostics Checklist to verify if public domains resolve.

If public domains resolution fails, check if you can resolve against a public resolver directly (e.g., nslookup google.com 8.8.8.8).

  • If direct resolution works: It's likely a NetBird resolver issue.
  • If direct resolution fails: It's likely a general network connectivity issue.

Solutions:

Solution A: No Primary Nameserver Configured

Check:

  1. Go to DNS → Nameservers
  2. Look for a nameserver with empty match domains (this is the primary)
  3. Verify it's assigned to your peer's distribution groups

Fix: Create a primary nameserver:

{
  "name": "Public DNS",
  "primary": true,
  "domains": [], // don't configure any match domains!
  "nameservers": [
    {"ip": "1.1.1.1", "ns_type": "udp", "port": 53},
    {"ip": "8.8.8.8", "ns_type": "udp", "port": 53}
  ],
  "groups": ["All Peers"]
}

Solution B: Primary Nameserver Unreachable

Your primary DNS server is down or unreachable.

Test:

# Test primary nameserver directly
dig @1.1.1.1 google.com
# If timeout, it's likely Network issue or firewall block

Fix:

  1. Add backup nameservers to the primary group
  2. Or switch to a different primary DNS:
{
  "nameservers": [
    {"ip": "1.1.1.1", "ns_type": "udp", "port": 53},
    {"ip": "1.0.0.1", "ns_type": "udp", "port": 53},
    {"ip": "8.8.8.8", "ns_type": "udp", "port": 53}
  ]
}

Solution C: DNS Management Disabled

The peer's group has DNS management disabled.

Check:

  1. Go to DNS → DNS Settings
  2. Look for peer's group in disabled_management_groups

Fix: Remove from disabled list or expected behavior.

Issue 3: Intermittent DNS Failures

Symptoms:

  • DNS works sometimes but not always
  • Queries timeout randomly
  • Slow DNS resolution

Diagnosis:

# Test multiple times
for i in {1..10}; do
  echo "Test $i:"
  time nslookup internal.company.internal
  sleep 1
done

# Look for:
# - Timeouts
# - Slow responses (>1 second)
# - Inconsistent results

Solutions:

Solution A: Nameserver Performance Issues

Test nameserver directly:

# Time direct queries to each nameserver
time dig @10.0.0.1 internal.company.internal
time dig @10.0.0.2 internal.company.internal

# If slow or timeout:
# → Nameserver is overloaded or having issues

Fix:

  1. Add more nameservers for load balancing
  2. Check nameserver health
  3. Consider caching DNS server closer to peers

Solution B: Network Instability

Check NetBird connectivity:

netbird status

# Should show: Status: Connected

# If shows disconnected/reconnecting:
# → Underlying network issues

Fix:

  • Check physical network connection
  • Verify firewall rules
  • Review NetBird logs: netbird up --log-level debug

Solution C: DNS Cache Issues

Clear DNS cache:

Linux:

# systemd-resolved
sudo systemd-resolve --flush-caches

# nscd
sudo systemctl restart nscd

macOS:

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

Windows:

ipconfig /flushdns

NetBird:

# Restart NetBird to clear its cache
netbird down && netbird up

Issue 4: Search Domains Not Working

Symptoms:

  • ping server doesn't work
  • ping server.company.internal does work
  • Short names aren't expanded

Diagnosis:

# Check search domains
cat /etc/resolv.conf

# Should contain:
# search company.internal

# Or on Windows:
Get-DnsClientGlobalSetting | Select-Object SuffixSearchList

Solutions:

Solution A: Search Domains Not Enabled

Check configuration:

  1. Go to DNS → Nameservers
  2. Find your internal domain nameserver
  3. Check Mark match domains as search domains is enabled

Fix:

{
  "domains": ["company.internal"],
  "search_domains_enabled": true  // Must be true!
}

Solution B: Multiple Search Domains Conflict

If you have multiple nameservers with search domains enabled, they may conflict.

Check:

cat /etc/resolv.conf

# If you see many search entries:
# search domain1.internal domain2.internal domain3.internal domain4.internal
# → OS may truncate or ignore some

Fix: Limit to 3-4 most important search domains.

Issue 5: DNS Works on NetBird Network, Fails Outside

Symptoms:

  • DNS works when connected to NetBird
  • DNS fails when NetBird disconnects
  • Computer can't resolve anything after using NetBird

Diagnosis:

# Disconnect NetBird
netbird down

# Check DNS
cat /etc/resolv.conf

# If still shows 100.x.255.254, NetBird didn't restore original DNS

Solutions:

Solution A: Manual DNS Restoration

Linux/macOS:

# Remove NetBird DNS manually
sudo rm /etc/resolv.conf
sudo ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
# or create new resolv.conf:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

Windows:

# Reset to automatic DNS
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ResetServerAddresses

Solution B: Clean Reinstall

If DNS keeps breaking:

# Completely remove NetBird
sudo netbird down
sudo systemctl stop netbird
sudo systemctl disable netbird

# Restore DNS manually (see above)

# Reinstall NetBird
curl -sSL https://pkgs.netbird.io/install.sh | sh

Issue 6: DNS Rebinding Protection

Symptoms:

  • Router blocks internal DNS queries
  • "DNS rebinding attack detected" in router logs
  • Inconsistent resolution

Diagnosis:

This happens when using NetBird DNS with routers that have DNS rebinding protection (pfSense, OpenWRT, etc.).

Solutions:

Solution A: Whitelist Domains

In your router's DNS settings, whitelist your internal domains:

pfSense:

  1. Services → DNS Resolver
  2. Add to "Domain Overrides" or whitelist

OpenWRT:

# Add to /etc/config/dhcp
config domain
    option name 'company.internal'
    option ip '10.0.0.1'

Verifying Configuration

Public nameservers

When you configure a nameserver accessible from the Internet (without a VPN), the NetBird client acts as a proxy to that public nameserver.

There are two things to verify:

  1. The NetBird client has picked up the nameserver
  2. The operating system is configured to use the NetBird client's proxy nameserver

To check the first item (works on all operating systems):

  1. Run netbird status -d
  2. Locate the nameserver's IP address
  3. Confirm it shows as "Available" (it could also show as timed out or in another state)
...
Nameservers:
  [1.1.1.1:53, 1.0.0.1:53] for [.] is Available
...

Verifying DNS resolution in practice

Here are commands to query nameservers for name.at.example.com on different operating systems. The trailing . ensures you're querying a fully-qualified domain name, independent of your local network's search domain configuration:

# macOS
dscacheutil -q host -a name name.at.example.com.
# Windows PowerShell
Resolve-DnsName -Name name.at.example.com.
# Linux/UNIX
dig name.at.example.com.
nslookup name.at.example.com.
# Linux with systemd-resolved
resolvectl query name.at.example.com.

Verifying nameserver registration on Windows

To confirm nameservers are properly registered on Windows using PowerShell:

PS C:\Users\kdn> Get-DnsClientNrptRule
Name                             : NetBird-Match
Version                          : 2
Namespace                        : {.netbird.cloud, .83.100.in-addr.arpa}
...
 NameServers                      : 100.83.255.254
...
PS C:\Users\kdn> Get-DnsClientNrptPolicy


Namespace                        : .83.100.in-addr.arpa
...
NameServers                      : 100.83.255.254
...

Namespace                        : .netbird.cloud
...
NameServers                      : 100.83.255.254
...

PS C:\Users\kdn> ipconfig /all
...
Unknown adapter wt0:

   Connection-specific DNS Suffix  . : netbird.cloud
   Description . . . . . . . . . . . : WireGuard Tunnel
...
   Connection-specific DNS Suffix Search List :
                                      netbird.cloud
                                      83.100.in-addr.arpa
...

In the output above, look for:

  • 100.XXX.255.254 under NameServers (the local proxy address of the NetBird client)
  • .netbird.cloud and .XXX.100.in-addr.arpa under Namespace for built-in entries
  • .your.custom.domain.example.com under Namespace for your custom domains

Verifying nameserver registration on macOS

To confirm nameservers are properly registered on macOS using the terminal:

> scutil --dns
...
resolver #2
  domain   : netbird.cloud
  nameserver[0] : 100.83.255.254
  port     : 53
  flags    : Supplemental, Request A records, Request AAAA records
  reach    : 0x00000002 (Reachable)
  order    : 101200
...
resolver #8
  domain   : 83.100.in-addr.arpa
  nameserver[0] : 100.83.255.254
  port     : 53
  flags    : Supplemental, Request A records, Request AAAA records
  reach    : 0x00000002 (Reachable)
  order    : 102402
...

In the output above, look for:

  • 100.XXX.255.254 under nameserver[N] (the local proxy address of the NetBird client)
  • netbird.cloud and .XXX.100.in-addr.arpa under domain for built-in entries
  • .your.custom.domain.example.com under domain for your custom domains
  • Reachable in the reach field
macOS DNS caching issues

macOS may cache DNS results from previous queries and continue serving stale data. To flush the cache:

sudo dscacheutil -flushcache && sudo killall -HUP mDNSResponder

To verify whether caching is causing your issue:

  1. Run netbird down or disconnect
  2. Flush the cache (see above)
  3. Resolve the domain: dscacheutil -q host -a name <domain>
  4. Run netbird up or connect
  5. Check if dscacheutil -q host -a name <domain> works
    • If it doesn't, flush the cache and retry

Verifying nameserver registration on Linux

Nameserver configuration varies depending on your distribution:

For systemd-resolved, check the configuration with resolvectl status.

For other configuration backends, look for these entries in /etc/resolv.conf:

  • 127.0.0.1 - default address for NetBird DNS proxy listener
  • 127.0.0.153 - fallback address for NetBird DNS proxy listener
  • Value of $NB_DNS_RESOLVER_ADDRESS - custom override for the NetBird DNS proxy listener

To find the address the NetBird client is listening on:

sudo ss -nlptu 'sport = 53' | grep netbird
sudo netstat -ltnup | grep ':53' | grep netbird

Internal nameservers

When you configure an internal nameserver (not accessible from the Internet), you need to complete the steps in the Public nameservers section above, plus verify that the nameserver's IP addresses are properly routed and accessible.

Refer to Access from peer-a to srv-c in the client troubleshooting guide.

To configure int-dns1, follow Access from peer-a to srv-c with these substitutions:

  • Replace port 80 with port 53
  • Replace IP address 10.123.45.17 with 10.123.45.6

To configure int-dns2, follow Access from peer-a to srv-c with these substitutions:

  • Replace port 80 with port 53
  • Ignore the 10.123.45.0/24 network instructions entirely
  • Replace IP address 10.123.45.17 with 10.7.8.9
  • Create a Network (with Resources and Routing Peers) or Network Route for the 10.7.8.9/32 IP address range

To test the configuration, refer to the Public nameservers section.

Debugging Access to Domain Resources

While we strive to make domain-based Resources "just work", issues can still occur. Common causes include:

  • Local device management software or system firewalls on the client
  • Routing Peer problems (often firewall-related)
  • Access Policies misconfiguration preventing connectivity

This section provides step-by-step guidance for verifying connectivity at each stage of Domain Resource handling, helping you identify where problems occur.

For a detailed overview of how this works, read the Domain Resources section.

We'll troubleshoot in reverse order, starting with the most common issues. First, we'll verify that the Routing Peer is working correctly, then check the client's operating system configuration as one of the final steps.

For the examples in this section, we'll assume:

  • A *.nb.test Network Resource is configured
  • We're trying to access srv.nb.test
  • zxc.nb.test doesn't exist (used to demonstrate errors)
  • The Routing Peer's NetBird address is 100.83.136.209
    • It's named brys-vm-nbt-ubuntu-isolated-02 in the outputs
  • The client is named brys-vm-nbt-ubuntu-01 in the outputs
    • The client runs Ubuntu, but most commands work across all platforms
    • Its IP address is 100.83.73.97
    • On macOS and Windows, use 100.83.255.254 to access the local DNS forwarder instead
  • The Resource runs on brys-vm-nbt-ubuntu-isolated-01 in the outputs
  • We'll only check port 22054, but you may need to repeat steps for port 5353 on legacy clients

Is the Routing Peer correctly resolving queries?

While this is rarely the issue in practice, it's worth verifying that the Routing Peer can resolve the requested domain and access the target resource.

Refer to Verifying DNS resolution in practice for OS-specific commands, adjusting the domain to srv.nb.test.

Also verify that the Routing Peer has network access to the routed resource:

For TCP services, you should see something like this:

kdn@brys-vm-nbt-ubuntu-01:~$ nc -vz -w 1 srv.nb.test 80
Connection to srv.nb.test (192.168.100.10) 80 port [tcp/http] succeeded!
kdn@brys-vm-nbt-ubuntu-01:~$ nc -vz -w 1 srv.nb.test 12345
nc: connect to srv.nb.test (192.168.100.10) port 12345 (tcp) failed: Connection refused

For UDP:

kdn@brys-vm-nbt-ubuntu-01:~$ nc -vz -w 1 -u srv.nb.test 12345 ; echo $?
Connection to srv.nb.test (192.168.100.10) 12345 port [udp/*] succeeded!
0
kdn@brys-vm-nbt-ubuntu-01:~$ nc -vz -w 1 -u srv.nb.test 12347 ; echo $?
1

Is the remote DNS resolver accessible to the client?

Verify that the client Peer can reach and use the Routing Peer's DNS resolver. This step rules out firewall-related issues with the Routing Peer. If the following command fails, you'll need to open port 22054 in the Routing Peer's firewall.

kdn@brys-vm-nbt-ubuntu-01:~$ nslookup -timeout=1 -port=22054 srv.nb.test 100.83.136.209
Server:         100.83.136.209
Address:        100.83.136.209#22054

Non-authoritative answer:
Name:   srv.nb.test
Address: 192.168.100.10

kdn@brys-vm-nbt-ubuntu-01:~$ nslookup -timeout=1 -port=22054 zxc.nb.test 100.83.136.209
Server:         100.83.136.209
Address:        100.83.136.209#22054

** server can't find zxc.nb.test: NXDOMAIN

Trigger the Domain Resource

While local DNS forwarder failures are rare, using it is a good way to force the NetBird client to set up routing for the domain (see Domain Resources for details).

Notice that the IP addresses are initially missing from the routing table (ip route show on Linux), but are added after resolving the domain for the first time using the local DNS Forwarder:

kdn@brys-vm-nbt-ubuntu-01:~$ netbird networks ls
Available Networks:

  - ID: *.nb.test
    Domains: *.nb.test
    Status: Selected
    Resolved IPs: -
kdn@brys-vm-nbt-ubuntu-01:~$ ip route show table all | grep 192.168.100
kdn@brys-vm-nbt-ubuntu-01:~$ nslookup -timeout=1 srv.nb.test 100.83.73.97
Server:         100.83.73.97
Address:        100.83.73.97#53

Non-authoritative answer:
Name:   srv.nb.test
Address: 192.168.100.10
kdn@brys-vm-nbt-ubuntu-01:~$ ip route show table all | grep 192.168.100
192.168.100.10 dev wt0 table 7120
kdn@brys-vm-nbt-ubuntu-01:~$ netbird networks ls
Available Networks:

  - ID: *.nb.test
    Domains: *.nb.test
    Status: Selected
    Resolved IPs:
      [srv.nb.test.]: 192.168.100.10

Verifying Domain Resource registration with the operating system

After confirming everything works within NetBird's scope, restart NetBird and check whether the operating system's default DNS resolver resolves the Domain Resource correctly.

We'll start fresh by restarting the entire NetBird service to purge all caches, then proceed with testing:

kdn@brys-vm-nbt-ubuntu-01:~$ sudo netbird service restart
NetBird service has been restarted
kdn@brys-vm-nbt-ubuntu-01:~$ netbird networks ls
Available Networks:

  - ID: *.nb.test
    Domains: *.nb.test
    Status: Selected
    Resolved IPs: -
kdn@brys-vm-nbt-ubuntu-01:~$ ip route show table all | grep 192.168.100
kdn@brys-vm-nbt-ubuntu-01:~$ resolvectl query srv.nb.test
srv.nb.test: 192.168.100.10                    -- link: wt0

-- Information acquired via protocol DNS in 8.1ms.
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no
-- Data from: network
kdn@brys-vm-nbt-ubuntu-01:~$ ip route show table all | grep 192.168.100
192.168.100.10 dev wt0 table 7120
kdn@brys-vm-nbt-ubuntu-01:~$ netbird networks ls
Available Networks:

  - ID: *.nb.test
    Domains: *.nb.test
    Status: Selected
    Resolved IPs:
      [srv.nb.test.]: 192.168.100.10

Prevention Checklist

Avoid future DNS issues:

  • ✅ Always configure at least one primary nameserver
  • ✅ Use 2-3 nameservers for redundancy
  • ✅ Test configuration on one peer before rolling out
  • ✅ Document your DNS architecture
  • ✅ Monitor DNS resolution performance
  • ✅ Keep NetBird client updated
  • ✅ Verify nameservers are reachable before configuring
  • ✅ Use fast, reliable public DNS for primary (Cloudflare, Google)
  • ✅ Set search_domains_enabled: true for internal domains