Inspect and Debug NetworkManager Without Guessing
NetworkManager will run for weeks on a stale profile or a device it quietly refuses to manage, and guessing which is broken wastes an evening. This guide shows you how to inspect the daemon that is actually running, read the configuration it actually loaded, and pull trace logs without touching a vendor file. It targets NetworkManager 1.46.0, installed here as network-manager 1.46.0-1ubuntu2.8. Allow 15 minutes for inspection, longer if you are chasing something intermittent.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a shell and a working NetworkManager install. Reading status and configuration is normally unprivileged; writing a config snippet and restarting the service needs sudo and can interrupt live connections.
1. Confirm the Daemon and Package
Prove which binary and package you are actually debugging first. It is a five-second check that saves you chasing a fault in the wrong installation, container or test build.
$ command -v NetworkManager
/usr/sbin/NetworkManager
$ NetworkManager --version
1.46.0
$ dpkg-query -W -f='${Package} ${Version}\n' network-manager
network-manager 1.46.0-1ubuntu2.8
$ systemctl show -p ActiveState,SubState NetworkManager
ActiveState=active
SubState=running
On another distribution the package query will differ, but NetworkManager --version and systemctl stay useful everywhere. If the unit is not active, stop here and chase the service failure before you touch configuration.
Checkpoint
You have the daemon version, package version and service state written down.
2. Read the Effective Configuration
Skip guessing from one file and ask the daemon what it actually merged:
$ NetworkManager --print-config
This prints and exits, it does not include connection profiles, inspect those separately with nmcli connection. On the reference system it shows /etc/NetworkManager/NetworkManager.conf, vendor snippets, dns=systemd-resolved, plugins=ifupdown,keyfile, and an unmanaged-devices rule that excludes everything except Wi-Fi and mobile broadband.
That merged view beats opening one file in isolation. NetworkManager reads vendor snippets from /usr/lib/NetworkManager/conf.d, then runtime snippets from /run/NetworkManager/conf.d, then the main file, then administrator snippets in /etc/NetworkManager/conf.d. Later files win. The internal file under /var/lib/NetworkManager is read last and is not for hand editing.
Put an administrator change in a new file under /etc/NetworkManager/conf.d, never in the distribution-owned main file, a package update can and will replace it. A name such as 95-local-debug.conf also makes the ordering obvious when you check the result later.
Checkpoint
You know which DNS backend, settings plugins and device rules are actually in effect, not the ones a tutorial for a different distribution assumed.
3. Check Live Devices and Profiles
The daemon configures devices, but nmcli is where you actually look at live state. Run these before you edit anything:
$ nmcli general status
$ nmcli device status
$ nmcli connection show
$ ip link show
$ ip address show
$ ip route show
Compare the device list against the profiles and the kernel's own addresses. An unmanaged device is not the same problem as a device with a broken profile: if NetworkManager calls something unmanaged, check the effective configuration and udev properties before trying to force it managed.
There are two different ideas behind the word "managed" here. A device rule such as device*.managed=1 can be overridden through the API. A keyfile unmanaged-devices rule is strict, and nmcli device set IFNAME managed yes cannot override it, which is why a command that looks correct can appear to do nothing.
If a profile exists on disk but NetworkManager cannot see it, run nmcli connection reload. The monitor-connection-files setting is deprecated and will not reload it for you.
Checkpoint
You can name the affected interface and profile, and you have checked addresses, routes and DNS separately.
4. Turn On Temporary Trace Logging
For a short, reproducible fault, runtime logging avoids leaving a file behind:
$ sudo nmcli general logging level TRACE domains ALL
$ nmcli general logging
Expect the second command to report LEVEL TRACE and every logging domain. Reproduce the problem, then pull only the relevant journal entries:
$ sudo journalctl -u NetworkManager --since '5 minutes ago' --no-pager
Trace output is deliberately noisy. It should not contain secrets, but it can still show IP addresses, interface names and your network layout, review it before you share it. Put logging back when you are done:
$ sudo nmcli general logging level INFO domains DEFAULT
This only changes the running daemon, it writes no persistent file. If your system already reports a different level or domain set, write that down first and restore it exactly rather than assuming the defaults.
5. Capture Logs From Daemon Startup
If the fault happens during startup, runtime logging starts too late to catch it. Drop in a dedicated administrator snippet instead:
$ sudo install -d -m 0755 /etc/NetworkManager/conf.d
$ sudo tee /etc/NetworkManager/conf.d/95-local-debug.conf > /dev/null <<'EOF'
[logging]
level=TRACE
domains=ALL
EOF
$ NetworkManager --print-config | sed -n '/^\[logging\]/,/^\[/p'
The printed section should show level=TRACE and domains=ALL. The next command restarts the service, so warn anyone else using the machine first:
$ sudo systemctl restart NetworkManager
$ systemctl show -p ActiveState,SubState NetworkManager
ActiveState=active
SubState=running
$ sudo journalctl -u NetworkManager -b --no-pager
A restart can briefly cut networking. Reproduce the issue, save the journal output, then remove the temporary snippet and restart again:
$ sudo rm /etc/NetworkManager/conf.d/95-local-debug.conf
$ sudo systemctl restart NetworkManager
Warning
Removing this file is the undo step. Only keep it if you deliberately want persistent trace logging and accept the privacy and volume trade-off. If the restart fails, restore connectivity through the local console or an out-of-band session, check journalctl -u NetworkManager -b, and do not keep restarting a remote host blind.
6. Reload the Right Thing
A signal is not a universal refresh button. SIGHUP reloads supported daemon configuration and can briefly interrupt name resolution because the DNS plugin may restart, but it does not reload connection profiles from disk. Use nmcli connection reload for profiles, and a full service restart when a setting cannot change at runtime.
For an ordinary configuration reload, go through the service manager so the action shows up in the journal:
$ sudo systemctl reload NetworkManager
$ sudo journalctl -u NetworkManager -n 30 --no-pager
Some settings still need a full restart, your installed manual is the authority for your version. After either action, check the effective configuration and live state again rather than trusting a clean exit status.
Done means
- Identity confirmed. You verified the NetworkManager binary, package version and service state.
- Config checked. You inspected the merged configuration with
NetworkManager --print-config. - Fault located. You identified the affected device, profile, address, route and DNS path.
- Logs reviewed. You used temporary trace logging to diagnose the fault and checked logs for private network details before sharing.
- Cleaned up. Any persistent debug snippet was removed, and the service was restarted and re-verified.