Query systemd-networkd State over D-Bus
Ping works but something upstream still calls the link down, so you want networkd's own view rather than a guess from ip addr. This guide inspects the systemd-networkd D-Bus interface, finds the object for a specific link, and tells a real network problem apart from a missing D-Bus service. Allow about fifteen minutes, all of it read-only.
The route
Jump straight to the step you need, or tick off Done means at the end.
This matches the installed systemd 255 manpage on this machine. D-Bus interfaces are versioned, so a newer systemd may expose more methods or properties; check before copying a command into automation.
1. Confirm you are inspecting the right service
Check the service state first. This needs no elevated privileges:
$ systemctl is-active systemd-networkd.service
active
$ systemctl is-enabled systemd-networkd.service
enabled
active is a useful checkpoint, but it does not prove the D-Bus name is available or that every link is managed. A host can have connectivity from another manager entirely, and networkd can deliberately leave links unmanaged.
Next, compare the high-level view:
$ networkctl list --no-pager
IDX LINK TYPE OPERATIONAL SETUP
1 lo loopback carrier unmanaged
2 enp0s31f6 ether routable configured
4 docker0 bridge routable unmanaged
Your names and rows will differ. Record the exact name you want to investigate, such as enp0s31f6. Do not guess a name in the D-Bus path.
2. Introspect the manager object
The manager object is always at /org/freedesktop/network1. Ask the system bus what it exposes:
$ gdbus introspect --system \
--dest org.freedesktop.network1 \
--object-path /org/freedesktop/network1
Look for the org.freedesktop.network1.Manager interface. On this version it includes read-oriented methods such as ListLinks, GetLinkByName, GetLinkByIndex, Describe and DescribeLink, alongside methods that can alter live DNS, NTP, resolver domains or link state. Seeing a method in introspection is not a reason to call it.
Expected output is long, with signatures similar to:
interface org.freedesktop.network1.Manager {
ListLinks(out a(iso) links);
GetLinkByName(in s name, out i ifindex, out o path);
Describe(out s json);
}
Checkpoint: if this prints Error connecting, stop here. A running unit is not enough if the service is not reachable on the system bus. Check systemctl status systemd-networkd.service --no-pager, recent logs with journalctl -u systemd-networkd.service -b --no-pager, and whether the host is actually running a different network manager. Do not work around this by changing network configuration.
3. Map an interface name to its object path
Use the manager method rather than constructing a path from memory. Replace IFACE with the name from networkctl list:
$ IFACE='enp0s31f6'
$ gdbus call --system \
--dest org.freedesktop.network1 \
--object-path /org/freedesktop/network1 \
--method org.freedesktop.network1.Manager.GetLinkByName \
"$IFACE"
(2, objectpath '/org/freedesktop/network1/link/_2')
The first value is the kernel interface index, the second is the link object path. That suffix is based on the numeric index, not the interface name, so it can change when a virtual device gets recreated.
If the result says the link cannot be found, check spelling and confirm networkd actually knows about the device. An interface can exist in the kernel with no corresponding managed link object in networkd. Check the service log before reaching for a runtime setter.
4. Read link status without changing it
Pass the object path into another introspection call:
$ gdbus introspect --system \
--dest org.freedesktop.network1 \
--object-path /org/freedesktop/network1/link/_2
The org.freedesktop.network1.Link interface exposes states including OperationalState, CarrierState, address states, OnlineState and AdministrativeState. These describe networkd's view at that moment, not a promise that an application can actually reach a remote service.
For a human-readable version of the same thing:
$ networkctl status "$IFACE" --no-pager
● 2: enp0s31f6
Link File: /usr/lib/systemd/network/99-default.link
Network File: /etc/systemd/network/20-wired.network
State: routable (configured)
Online state: online
Output varies by host and networkctl version. What matters is whether the link path, operational state and network file agree with what you expected going in.
5. Pull the manager description for config debugging
The interface also serves a JSON description of the manager, no arguments needed:
$ gdbus call --system \
--dest org.freedesktop.network1 \
--object-path /org/freedesktop/network1 \
--method org.freedesktop.network1.Manager.Describe
The returned string is JSON, and easier to diff than a screen-wide introspection dump. To keep a copy for comparison:
$ gdbus call --system \
--dest org.freedesktop.network1 \
--object-path /org/freedesktop/network1 \
--method org.freedesktop.network1.Manager.Describe > networkd-manager.txt
That file holds the D-Bus return wrapper as well as the JSON, so treat it as a diagnostic capture rather than a stable file format. Example: check it, then clean up:
$ less networkd-manager.txt
$ rm -- networkd-manager.txt
Recovery: the removal above is irreversible. If you need the record kept, move it to an approved diagnostic location instead of deleting it.
6. Keep inspection separate from live changes
Warning
The manager and link interfaces include methods such as SetLinkDNS, SetLinkNTP, SetLinkDomains, ReconfigureLink and Reload. These are not harmless queries: they can change resolver behaviour, trigger DHCP activity or interrupt a link, and what is allowed depends on the host's D-Bus policy.
Do not test these against a remote production host just to learn their argument syntax. For persistent configuration, edit the intended .network or .netdev file with a backup and a recovery path, then use the documented networkd reload workflow. The interface offers RevertDNS and RevertNTP for their corresponding transient settings, but there is no single undo method that covers every possible change.
After any authorised change, check both the affected link and the overall state:
$ networkctl status "$IFACE" --no-pager
$ networkctl status --no-pager
Only use sudo where the host actually requires it. Read-only gdbus and networkctl checks normally work as an ordinary user.
Done means
- Confirmed
systemd-networkd.serviceas the service under inspection. - Introspected the manager object successfully on the system bus.
- Mapped the target interface name to its current index and object path.
- Compared link status from D-Bus against
networkctl. - Called no live setter without an explicit change plan and recovery path.