WiFi on Linux works reliably for many people until, one day, it doesn't show up in the tray. Or it shows up twice. Or the password dialog opens but immediately closes. Or you switch to a Wayland compositor and the network icon vanishes entirely. Most walkthroughs explain what to install. Very few explain the architecture underneath -- the GTK library that nm-applet links against, the tray protocol your desktop expects, the backend daemon negotiating with your kernel WiFi driver. This article covers all of it.
We'll walk from the kernel up: how Linux represents a wireless interface, how wpa_supplicant and iwd differ as backends, how NetworkManager sits on top of both, how the GTK applet renders into a system tray using either XEmbed or the StatusNotifierItem specification, and the exact command-line hooks that let you manage all of it without a GUI in sight.
The Full Stack: From Kernel to GTK
Before touching any package manager command, it helps to see the whole picture. WiFi on a modern Linux desktop involves at least five distinct software layers, each with its own configuration surface and failure modes.
At the bottom is the kernel driver and cfg80211. The cfg80211 subsystem, introduced in Linux 2.6.22, is the kernel's unified API for wireless device configuration. Every driver that wants to work with userspace tools must register through cfg80211. Above cfg80211 sits the nl80211 interface, the socket-based mechanism through which userspace programs send commands and receive events. When you scan for networks, associate with an access point, or negotiate WPA keys, nl80211 is the pipe.
Above the kernel sits the authentication daemon -- either wpa_supplicant or iwd. These daemons own the authentication state machine. They speak EAP, handle the 4-way WPA2 handshake, manage roaming logic, and expose a API that higher layers call. NetworkManager then sits above the authentication daemon as a policy engine, deciding which network to join based on your saved profiles, Polkit permissions, and priority rules. NetworkManager itself exposes a well-documented D-Bus API at org.freedesktop.NetworkManager.
Finally, at the top, nm-applet is the GTK front-end that reads NetworkManager's D-Bus interface and renders a system tray icon. It does not talk to wpa_supplicant or iwd directly. It does not touch nl80211. It only speaks to NetworkManager.
nm-applet is not a WiFi tool. It is a NetworkManager display tool that happens to show WiFi. The implication: a missing tray icon and a failed connection are two entirely different problems. A missing icon is a UI layer problem (GTK, tray protocol, display server). A failed connection is a daemon layer problem (NetworkManager, wpa_supplicant/iwd, kernel driver). Conflating them sends you down the wrong diagnostic path.
network-manager-applet (nm-applet + nm-connection-editor)org.freedesktop.NetworkManager/etc/NetworkManager/NetworkManager.conf and /etc/NetworkManager/system-connections/journalctl -u NetworkManagerjournalctl -u wpa_supplicant or -u iwdcfg80211 is the kernel's unified wireless config API (since 2.6.22); nl80211 is the Netlink socket userspace uses to talk to itnmcli device status — diagnose with lspci -k and dmesglinux-firmware, iwl-firmware, realtek-firmwareiwlwifi — Atheros: ath9k, ath11k — Realtek: rtw89, rtl8xxxu — Broadcom: brcmfmaclspci -k | grep -A 3 -i wireless — look for "Kernel driver in use"; absence means no driver bounddmesg as "Direct firmware load for <file> failed with error -2"A failure at any layer produces identical symptoms at the top: no WiFi. The stack diagram above identifies which layer owns each class of problem.
nm-applet and the libnma Library
nm-applet is the package many distributions ship as network-manager-applet. For historical reasons many guides still refer to the older network-manager-gnome package name, which in Debian-based systems now exists only as a transitional package that pulls in both network-manager-applet and the separately packaged nm-connection-editor. It provides two executables: nm-applet, the tray process, and nm-connection-editor, the standalone GUI for creating and editing connection profiles.
The upstream manpage defines the applet's role clearly: it is a GTK-based tool for monitoring network status and toggling connections managed by NetworkManager. Per the nm-applet(1) manpage, it is "normally started at login by the desktop session manager" and requires no manual invocation under standard desktop setups.
The applet depends on libnma, a companion library that provides the GTK dialogs and UI widgets NetworkManager-aware applications use. libnma handles the password prompts, the certificate file pickers for 802.1X enterprise networks, and the mobile broadband wizard. Without it, nm-applet cannot display its connection editor dialog.
As of the current stable ecosystem, libnma ships in two parallel variants that matter enormously depending on your desktop:
- libnma (GTK 3) -- the traditional library, present in virtually all distributions, required by nm-applet which remains a GTK 3 application
- libnma-gtk4 -- a GTK 4 port of the same dialogs, introduced to support GNOME Shell extensions and applications migrating to GTK 4
Debian's package description for libnma-gtk4-dev confirms: "The libnma-gtk4 library provides GTK 4 dialogs and UI utilities for NetworkManager." Both libraries can be installed simultaneously since they export different symbols. The GTK 4 variant is currently required by networkmanager-openvpn when running inside GNOME Shell, which has fully migrated to GTK 4.
On many distributions you'll see libnm-gtk (old), libnma (current GTK 3), and libnma-gtk4 (GTK 4 port). These are not the same. If nm-applet fails to launch with a missing symbol error, verify you have the correct libnma variant installed, not just the GTK 4 one.
The current stable upstream release of network-manager-applet is 1.36.0 (released January 2024). The primary new feature in 1.36.0 was UI support for the stable-ssid MAC address randomization mode. Building from source requires GTK 3.24.51 or later and libnma of a matching version. Building it also requires Polkit for authorization -- specifically, a running Polkit authentication agent so that non-root users can modify network connections without sudo. Optional build-time dependencies include gnome-bluetooth, jansson for JSON handling, and the ayatana-appindicator library for AppIndicator support (the legacy libindicator has been deprecated; distributions now use ayatana-appindicator3).
Debian made a significant packaging change in network-manager-applet 1.36.0-3 (November 2024): nm-applet and nm-connection-editor were split into separate binary packages. Desktop environments that only need the connection editor no longer have to pull in the tray applet as a dependency. A transitional network-manager-gnome package still installs both for existing setups. This split is propagated to Ubuntu 25.04 (Plucky) and later.
GNOME Shell: Why You Don't See nm-applet There
If you are running a full GNOME Shell desktop, nm-applet is not what renders your network indicator. GNOME Shell has its own built-in network panel, implemented as a Shell extension that talks directly to NetworkManager over D-Bus using libnma-gtk4. This panel replaces nm-applet entirely -- which is why installing network-manager-applet on GNOME and then looking for a tray icon produces nothing. GNOME Shell intentionally does not support XEmbed-based system tray icons as of GNOME 3.26, and while third-party extensions like TopIcons Plus and KStatusNotifierItem/AppIndicator Support can restore a tray area, GNOME's official position is that status icons belong in the panel, not an arbitrary tray.
The practical consequence: nm-applet is the right tool for standalone window managers (i3, Sway, Openbox, bspwm, herbstluftwm) and for lighter desktop environments (Xfce, LXQt, MATE) that do not ship their own NetworkManager panel. On GNOME, the connection editor -- nm-connection-editor -- remains useful for editing profiles that the GNOME Settings panel does not expose, such as custom routing tables or certain 802.1X certificate configurations. That is the primary reason to install the applet package on GNOME at all.
On GNOME Shell, skip nm-applet entirely and install only nm-connection-editor for access to advanced connection settings. Since Debian 1.36.0-3 and Ubuntu 25.04, the two are separate packages. Running nm-applet on a GNOME session will start a secrets agent in the background, which is harmless but redundant -- GNOME Keyring already handles that role.
The XEmbed vs StatusNotifierItem Problem
builds on nm-applet / libnma stack layers
This is where many WiFi tray icon issues originate, and it is almost never discussed in beginner guides.
There are two competing protocols for system tray icons on Linux. The original approach, XEmbed, is an X11 mechanism where an application renders its icon into a window that the system tray then "embeds" by reparenting it. nm-applet used XEmbed by default for many years. It still does, unless you tell it otherwise.
The problem is that Wayland does not support XEmbed. There is no concept of reparenting windows across Wayland clients. Accordingly, when nm-applet runs under a Wayland compositor with no XEmbed compatibility layer, its default behavior produces no visible icon at all. The process is running. NetworkManager is running. But there is nothing in your tray.
The tray protocol and the display server are not the same thing. XEmbed is an X11 mechanism; Wayland has no equivalent. StatusNotifierItem is a D-Bus specification -- it works wherever D-Bus works, including Wayland. This is why --indicator fixes the problem: it switches the tray mechanism from a display-server-dependent embedding protocol to a display-server-agnostic bus interface. The compositor draws the icon; nm-applet just publishes data to a bus object.
Dan Williams, a long-time NetworkManager maintainer at Red Hat, addressed this directly in a developer blog post on the GNOME blog. He described how Wayland's arrival made the XEmbed approach untenable for status icons — desktop environments wanted more rendering control — and explained that the team enhanced GTK3 AppIndicator support and added "an indicator mode to nm-applet based off Ubuntu's work." (Dan Williams, GNOME developer blog)
The solution is StatusNotifierItem (SNI), the freedesktop.org specification that replaces XEmbed for tray icons. SNI exposes the icon as a D-Bus object. The tray host reads that object and draws the icon itself, meaning the compositor has full control over rendering. KDE Plasma migrated to SNI-only years ago. GNOME uses its own Shell extensions for this. Xfce added a Status Notifier plugin in 4.14 and unified it with the Notification Area into a Status Tray plugin in 4.16.
To run nm-applet in SNI mode (which works on Wayland), you pass the --indicator flag:
$ nm-applet --indicator
For Sway users, this is documented directly in the Sway ecosystem. Elmord's blog on the Wayland transition confirmed the issue: the default nm-applet startup produces no visible icon because Swaybar does not support XEmbed, and the fix requires passing --indicator at launch. For i3 or openbox users who want nm-applet in a standalone tray, the tools stalonetray and trayer provide an XEmbed-compatible tray that works on X11 sessions.
There is an important behavioral change introduced in nm-applet 1.32.0 (April 2023) that most guides miss: the applet now automatically prefers AppIndicator/SNI when running outside X11, without requiring you to pass --indicator explicitly. The OpenSUSE package changelog records this directly: nm-applet 1.32.0 adds "Prefer using AppIndicator outside X11." This means that on most current Wayland sessions, if the AppIndicator support was compiled in, nm-applet will self-select SNI mode at startup. The --indicator flag remains the reliable explicit override and is still the correct answer when troubleshooting a missing icon -- but it is no longer the only path.
A related ecosystem shift: the original Ubuntu libindicator / appindicator3 library has been effectively replaced by the fork (ayatana-appindicator3). Since mid-2024, OpenSUSE Tumbleweed switched nm-applet's build dependency from appindicator3-0.1 to ayatana-appindicator3-0.1. Fedora made the same transition. If a distribution build of nm-applet shows no icon on Wayland even after restarting, the first thing to check is whether the ayatana-appindicator3 library is installed and whether your tray host supports the SNI D-Bus protocol.
Installation Across Distributions
The package names are consistent enough to follow a clear pattern. The core NetworkManager daemon and the GTK applet are typically separate packages.
$ sudo apt install network-manager network-manager-gnome # network-manager-gnome provides both nm-applet and nm-connection-editor # On older Ubuntu the transitional package name was network-manager-applet
$ sudo pacman -S networkmanager network-manager-applet $ sudo systemctl enable --now NetworkManager
$ sudo dnf install NetworkManager NetworkManager-tui nm-connection-editor # Fedora ships nm-applet as part of GNOME by default # For non-GNOME: install network-manager-applet
NetworkManager conflicts with other network management services. If you have systemd-networkd, dhcpcd, netifrc, or ifupdown also managing interfaces, unpredictable behavior will result. Disable and stop all competing services before enabling NetworkManager. The Gentoo wiki is explicit: "Be sure only one network management service is running at a time."
wpa_supplicant vs iwd: Choosing a WiFi Backend
builds on stack layers
NetworkManager does not directly implement the WPA authentication handshake. It delegates that to a backend daemon: historically wpa_supplicant, and increasingly the newer iwd (iNet wireless daemon) from Intel.
The backend choice affects what NetworkManager can automate, not just performance. wpa_supplicant lets NetworkManager fully manage 802.1X enterprise profiles through the GUI. iwd requires you to write provisioning files by hand for those same profiles -- NetworkManager cannot generate them. The practical consequence: iwd is a genuine upgrade for home and casual use; it is a workflow change for enterprise environments. Choose based on your authentication requirements, not codebase aesthetics.
wpa_supplicant
wpa_supplicant has been the default Linux WiFi authentication daemon since the mid-2000s. It supports WPA, WPA2, WPA3, 802.1X enterprise EAP methods, and a wide range of hardware. It communicates with the kernel via nl80211 and with NetworkManager via D-Bus. The Arch Wiki notes that NetworkManager 1.2 ported all its wpa_supplicant communication from the deprecated dbus-glib library to GDBus, improving stability and maintainability.
wpa_supplicant's main criticism is a complex, sprawling codebase. It works, but its configuration files are cryptic and the debug output is verbose.
iwd
iwd was developed by Intel as a modern, Linux-only replacement. It uses only kernel features rather than large userspace libraries, has a smaller codebase, and implements its own DHCP client and DNS resolution in standalone mode. The Fedora community describes it as "more modern" with a leaner, less tangled codebase compared to wpa_supplicant.
To switch NetworkManager to use iwd, edit /etc/NetworkManager/NetworkManager.conf:
[device] wifi.backend=iwd
Then stop wpa_supplicant, start iwd, and restart NetworkManager:
$ sudo systemctl disable --now wpa_supplicant $ sudo systemctl enable --now iwd $ sudo systemctl restart NetworkManager
iwd is not a drop-in replacement without caveats. The Debian wiki notes that as of its documentation, NetworkManager does not reconnect a connection dropped by the other side when using iwd as backend, and connections created with wpa_supplicant are not automatically reused with iwd. Passwords will need to be re-entered. The Gentoo wiki recommends iwd as the modern choice but notes that 802.1X enterprise connections require a manually written provisioning file in /var/lib/iwd/ because NetworkManager cannot auto-generate them under iwd. Always have a fallback plan before switching backends.
For Alpine Linux users, the NetworkManager wiki specifies installing the networkmanager-wifi subpackage to enable WiFi device plugin support, then choosing a backend in the config file's [device] section. Both backends can also configure MAC address randomization: setting wifi.scan-rand-mac-address=yes enables per-scan MAC randomization, which is useful for privacy on public networks.
Key Configuration: NetworkManager.conf and Connection Profiles
NetworkManager reads its global configuration from /etc/NetworkManager/NetworkManager.conf and individual connection profiles from /etc/NetworkManager/system-connections/. Connection profiles are INI-style files with sections for each setting domain.
A minimal WPA2 connection profile looks like this:
[connection] id=HomeWifi uuid=a1b2c3d4-e5f6-7890-abcd-ef1234567890 type=wifi autoconnect=true [wifi] mode=infrastructure ssid=MyNetworkName cloned-mac-address=stable-ssid [wifi-security] auth-alg=open key-mgmt=wpa-psk psk=yourpassphrase [ipv4] method=auto [ipv6] method=auto
The cloned-mac-address=stable-ssid value is worth noting specifically. NetworkManager 1.46, released in February 2024, added support for this option, randomizing the MAC address based on the WiFi network SSID in a deterministic but per-network way -- avoiding both the fingerprinting risk of a static MAC and the connectivity problems caused by a fully random one. nm-applet 1.36.0 added the corresponding UI for selecting this mode in nm-connection-editor. Fedora adopted stable-ssid as a privacy-conscious default for new connections.
MAC Randomization Modes Explained
NetworkManager supports several cloned-mac-address values and it is worth understanding what each one does before choosing. The permanent value disables randomization and sends the hardware-burned MAC -- the same value that appears in ip link before NetworkManager claims the interface. The random value generates a fully random MAC on every connection attempt, which is the strongest privacy option but can break captive portals that track sessions by MAC address. The stable value generates a consistent MAC tied to the machine and connection profile (not just the SSID), so the same MAC appears on the same network across reboots but differs between networks. The stable-ssid value added in 1.46 derives the MAC from the SSID alone, meaning the same MAC appears on a given network from any machine where this profile exists -- more portable than stable, less fingerprintable than permanent.
Separately, wifi.scan-rand-mac-address=yes in NetworkManager.conf controls whether probe requests during WiFi scanning use a random MAC. This is independent of the connection MAC. Enabling it prevents passive tracking of your device by access points you never connect to, which is the primary wireless privacy concern on public networks. The two settings operate at different points in the WiFi lifecycle and can be configured independently.
NetworkManager 1.48 (May 2024) improved 6 GHz band detection accuracy and added the ability to configure OpenSSL cipher suites for 802.1X authentication via 802-1x.openssl-ciphers. The daemon has continued to evolve: NetworkManager 1.52 (February 2025) added IPvlan interface support, a Dnsconfd plugin for system-wide DNS caching, and moved nmcli interactive history to $XDG_CACHE_HOME/nmcli-history. NetworkManager 1.54 (August 2025), the current stable release at time of writing, added per-device IPv4 forwarding configuration via ipv4.forwarding, loopback interface configuration in nmtui, and improved WireGuard IPv6 firewall rule handling. The nm-applet GTK frontend has not been updated since 1.36.0; it remains fully compatible with all NM daemon versions through 1.54.
The Arch Wiki notes that when a connection profile is configured to be available to all users, NetworkManager stores the passphrase in plaintext within a file that is only root-accessible. If you are on a shared machine, store secrets in a keyring (GNOME Keyring, KDE Wallet, or KeePassXC) using the libsecret Secret Service D-Bus API rather than in the connection profile directly.
A security vulnerability, CVE-2025-9615, was addressed in NetworkManager 1.52.2 (December 2025). Fedora 42 shipped the fix as a security update. If you are running an older NetworkManager daemon, check your distribution's security advisories and apply available updates. The vulnerability is in the daemon layer, not in nm-applet itself, but all NM-based setups are potentially affected. See the upstream merge request for full remediation details.
nmcli: Managing WiFi Without a GTK Applet
nm-applet is a convenience. Everything it does, nmcli can do from the terminal. This matters on headless systems, Wayland sessions without a compatible tray, or environments where you simply prefer the command line.
# Show all WiFi networks in range $ nmcli device wifi list # Connect to a network (will prompt for password) $ nmcli device wifi connect "MySSID" --ask # Show all saved connections $ nmcli connection show # Bring up a saved connection by name $ nmcli connection up "HomeWifi" # Disconnect a device $ nmcli device disconnect wlan0 # Toggle WiFi radio on/off $ nmcli radio wifi off $ nmcli radio wifi on # Show device status with signal strength $ nmcli device wifi list ifname wlan0
There is also nmtui, the ncurses text-user-interface shipped with NetworkManager itself. The Arch Wiki documents it as a tool for managing connections, the system hostname, and radio switches, launchable simply by running nmtui. Unlike nm-applet, nmtui does not require a running display server or any GTK libraries, making it the correct tool for SSH sessions and recovery environments.
Secrets Storage and the Keyring
builds on nm-applet / libnma
nm-applet is not just a display widget. It also functions as a NetworkManager secrets agent. When NetworkManager needs a password it does not have stored -- for a new network, an expired certificate, or a connection that requires user authentication -- it broadcasts a D-Bus request to registered secrets agents. nm-applet receives that request and pops up the password dialog.
nm-applet plays two distinct roles simultaneously: a status display (the tray icon) and a secrets provider (the password dialog). These roles are independent. The tray icon can disappear while the secrets agent keeps running in the background. Conversely, killing nm-applet to fix a tray problem also removes the secrets agent -- which is why reconnecting to a new network immediately after a restart of nm-applet may prompt for a password even if the keyring has it stored. The agent needs a moment to re-register over D-Bus.
If nm-applet is not running when NetworkManager requests secrets, the connection will fail with a message like "No agents were available for this request." This is a common failure mode in minimal desktop setups or after a crash. Restarting nm-applet restores the secrets agent without requiring a full session restart:
For GNOME Keyring integration in minimal X11 sessions (not running a full GNOME desktop), the Gentoo wiki provides the required ~/.xinitrc snippet to launch the keyring daemon and export its socket address before starting nm-applet:
# Ensure D-Bus session is running if [[ -z "${DBUS_SESSION_BUS_ADDRESS}" ]]; then eval $(dbus-launch --sh-syntax --exit-with-session) fi # Start GNOME Keyring daemon for secrets, SSH, and GPG export $(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh,gpg) # Start nm-applet (will register as secrets agent) nm-applet &
Troubleshooting: When nm-applet Does Not Show Up
builds on tray protocols stack layers
The symptom is almost always the same: nm-applet is running (you can verify with ps aux | grep nm-applet), NetworkManager is running, but there is no icon in the system tray. The cause is one of a small set of problems.
Wrong tray protocol
On Wayland or on Xfce with the Status Notifier plugin (rather than the legacy Notification Area plugin), nm-applet's default XEmbed icon will not appear. Kill the running instance and restart with --indicator:
$ killall nm-applet $ nm-applet --indicator &
No systray available at all
Window managers like i3, bspwm, or herbstluftwm do not include a system tray by default. You need a standalone tray application. stalonetray is the standard choice for XEmbed-based trays on X11. Add it to your ~/.xinitrc or session autostart before nm-applet launches.
Duplicate icons
This occurs when both the Status Notifier plugin and the Notification Area plugin are active in Xfce simultaneously, or when multiple nm-applet instances are running. The Xfce forums confirm the fix: remove duplicate panel plugins, keep only one instance running, and if the session manager has saved old instances, clear the session with "Save session" unchecked on logout.
D-Bus session not available
nm-applet requires a D-Bus session bus. If launched too early in the login sequence before dbus-daemon has started, it will exit silently. Confirm D-Bus is running with echo $DBUS_SESSION_BUS_ADDRESS. If the variable is empty, start D-Bus manually before nm-applet.
Polkit agent missing
Modifying network connections from nm-applet requires a running authentication agent. On GNOME and KDE this is started automatically. On minimal desktops you must start one explicitly -- lxpolkit, polkit-gnome-authentication-agent-1, or xfce-polkit depending on what is installed.
rfkill soft block
If the WiFi interface appears in NetworkManager but cannot connect, check state. Some Lenovo laptops with the ideapad_laptop kernel module suffer from a soft block that persists even after toggling the hardware switch. The Arch Wiki recommends unloading the module as a workaround: sudo modprobe -r ideapad_laptop. The long-term fix involves kernel parameters.
$ rfkill list # Look for "Soft blocked: yes" on your WiFi entry # Unblock with: $ rfkill unblock wifi
WiFi interface does not appear at all
If nmcli device status shows no WiFi device -- not "unavailable," but genuinely absent -- the problem is below NetworkManager in the kernel driver layer. The sequence to diagnose this starts with verifying whether the kernel can see the hardware at all, then whether the correct driver module is loaded.
# List all PCI wireless devices (most internal WiFi cards are PCI/PCIe) $ lspci -k | grep -A 3 -i wireless # List USB wireless devices (USB adapters show here) $ lsusb # Check which driver is bound to the wireless device $ lspci -k | grep -A 3 -i network # Look for "Kernel driver in use: iwlwifi" or "ath9k" etc. # If this line is missing, no driver is loaded for that device # Check dmesg for driver errors at boot $ dmesg | grep -i -E 'wifi|wireless|iwl|ath|rtw|brcm' # List currently loaded wireless modules $ lsmod | grep -E 'iwl|ath|rtw|brcm|mt76|mac80211'
The lspci -k output's "Kernel driver in use:" line is the key signal. If it is absent, the kernel does not have a driver bound to the device -- either the driver module is not installed, not loaded, or the firmware blob is missing. Many WiFi drivers require a separate firmware package that is not included in the kernel itself. Common examples: iwlwifi requires firmware from linux-firmware (or distribution-specific iwl-firmware packages), and Realtek rtw89-based adapters need realtek-firmware or the equivalent. On Debian and Ubuntu, firmware is split into the non-free firmware packages. If dmesg shows a line like iwlwifi: Direct firmware load for iwlwifi-*.ucode failed with error -2, the firmware package is missing, not the driver.
After installing a missing firmware package, you do not always need a reboot. Try sudo modprobe -r iwlwifi && sudo modprobe iwlwifi (or substitute your driver name) to reload the module and pick up the newly installed firmware. If nmcli device status shows a WiFi interface afterward, you found the problem.
Reading daemon logs to go deeper
When tray-level diagnostics are inconclusive, the next step is reading NetworkManager and wpa_supplicant logs directly. Both daemons log through systemd's journal on modern distributions.
# Follow live NetworkManager log output $ journalctl -u NetworkManager -f # Show the last 100 NM log lines $ journalctl -u NetworkManager -n 100 --no-pager # wpa_supplicant log (when used as backend) $ journalctl -u wpa_supplicant -n 100 --no-pager # iwd log (when used as backend) $ journalctl -u iwd -n 100 --no-pager # Enable verbose NM logging temporarily (reverts on daemon restart) $ nmcli general logging level DEBUG domains WIFI,DEVICE,CORE # After diagnosing, restore default logging: $ nmcli general logging level INFO domains DEFAULT
The nmcli general logging command lets you raise verbosity without editing config files or restarting the daemon. Setting the WIFI domain to DEBUG produces scan results, association state machine transitions, and authentication exchange details -- enough to pinpoint whether the failure is in scanning, authentication, or IP address acquisition. When done, restore the level to INFO or DEFAULT; leaving DEBUG active generates a large volume of journal entries and can obscure other system logs.
D-Bus name conflict: multiple secrets agents competing
A subtler failure mode occurs when another process has already claimed the NetworkManager secrets agent D-Bus name on the session bus before nm-applet registers. This happens most often in environments that start both gnome-keyring-daemon and nm-applet without coordinating their startup order, or when a previous nm-applet crash left a stale D-Bus registration that the bus has not yet cleaned up. The symptom is nm-applet appearing to run normally -- the tray icon shows -- but password dialogs never appear when NetworkManager requests credentials. The connection times out with "No agents were available."
To diagnose, query the session bus directly for registered secrets agent names:
# List all names currently registered on the session bus $ dbus-send --session --print-reply --dest=org.freedesktop.DBus \ /org/freedesktop/DBus org.freedesktop.DBus.ListNames # Check whether nm-applet holds the agent registration $ dbus-send --session --print-reply --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager/AgentManager \ org.freedesktop.DBus.Introspect # Kill all applet instances and re-register cleanly $ killall nm-applet; sleep 1; nm-applet --indicator &
SNI tray host not implementing the full StatusNotifierWatcher spec
Not all StatusNotifierItem hosts are equal. The SNI specification requires a StatusNotifierWatcher process running on the session bus at org.kde.StatusNotifierWatcher to broker registrations between applets and the tray host. Many minimal window manager setups install a tray applet that renders SNI icons but does not start the Watcher, which means nm-applet's --indicator registration call silently fails -- there is no host to receive it.
The solution is to ensure a compliant Watcher is running. On systems using snixembed, stalonetray with SNI support compiled in, or xembedsniproxy (shipped with KDE Plasma), the Watcher is started automatically. On minimal setups, you may need to start xembedsniproxy explicitly or switch to a tray application that bundles a Watcher, such as waybar on Wayland or polybar on X11 (both implement the full SNI Watcher interface). Verify the Watcher presence with:
# Check whether the SNI Watcher is registered on the session bus $ dbus-send --session --print-reply --dest=org.freedesktop.DBus \ /org/freedesktop/DBus org.freedesktop.DBus.NameHasOwner \ string:org.kde.StatusNotifierWatcher # Returns: boolean true if a Watcher is present, false if not
Autostart race: nm-applet launched before the session bus or compositor is ready
On bare window managers that manage their own autostart (i3 exec, Openbox autostart, .xinitrc), nm-applet is sometimes launched too early -- before the compositing layer, SNI Watcher, or D-Bus session has finished initializing. The result is an applet that starts, finds no tray host, registers nothing, and then shows a blank tray slot or disappears. Unlike a missing-icon bug, this is a timing bug: restarting nm-applet manually ten seconds into the session works fine.
The correct fix is not a sleep hack but a proper dependency chain. On systemd-based desktops, create a user service unit for nm-applet that declares an ordering dependency:
[Unit] Description=NetworkManager applet After=graphical-session.target PartOf=graphical-session.target [Service] Type=simple ExecStart=/usr/bin/nm-applet --indicator Restart=on-failure RestartSec=3 [Install] WantedBy=graphical-session.target
Enable with systemctl --user enable --now nm-applet.service. The After=graphical-session.target directive ensures nm-applet does not start until the compositor and session bus are confirmed ready. The Restart=on-failure directive handles the edge case where the applet crashes during SNI registration and would otherwise disappear silently.
Connection profile permission mismatch: system vs user profiles
NetworkManager connection profiles stored in /etc/NetworkManager/system-connections/ are system-level profiles, available to all users and managed through Polkit. Profiles created by nm-applet running as a user may instead land in ~/.config/NetworkManager/system-connections/ depending on the NM version and configuration. When the profile exists in the wrong location -- or with incorrect file permissions -- NetworkManager can see it but not activate it for the relevant user without Polkit elevation, producing a silent connection failure with no error visible in the applet.
Verify where profiles actually live and what permissions they carry:
# List all connection profiles NM knows about, with UUIDs $ nmcli connection show # Show where a specific profile's file lives $ nmcli -f NAME,FILENAME connection show # Connection files must be owned by root and not world-readable $ ls -la /etc/NetworkManager/system-connections/ # Correct: -rw------- root root # If permissions are wrong, NM will log a warning and may not load the file # Fix permissions if needed $ sudo chmod 600 /etc/NetworkManager/system-connections/MyNetwork.nmconnection $ sudo chown root:root /etc/NetworkManager/system-connections/MyNetwork.nmconnection
The permissions key inside a connection profile also controls which system users can activate it. A profile with permissions=user:alice: under [connection] will only be activatable by the user alice. If you need a profile to be activatable by any user, remove the permissions key entirely or set it to an empty value. This is the correct solution for shared machines or kiosk setups where multiple users need WiFi access without the overhead of individual per-user profiles.
WiFi Scanning Behavior
NetworkManager performs a background WiFi scan every two minutes by default. This is the source of a specific class of issues: on some drivers, scanning while associated with an access point causes brief packet loss, VPN reconnect cycles, or stale DHCP leases. The Arch Wiki documents that certain WiFi drivers exhibit instability during background scans while connected, with symptoms including VPN disconnects and pages failing to load.
The fix is to lock the BSSID of your access point in the connection profile, which suppresses background roaming scans. You can set this in nm-connection-editor under the WiFi tab, or directly in the connection file:
[wifi] ssid=MyNetworkName bssid=AA:BB:CC:DD:EE:FF # Locking the BSSID disables background scanning for this connection
Internally, NetworkManager coordinates its scan list with wpa_supplicant's BSS list rather than maintaining a separate internal one. The NetworkManager blog explains that the daemon "threw away the internal NetworkManager list and just followed the supplicant's list" -- an improvement that reduces duplicate state and gives wpa_supplicant's better-informed roaming logic full control. Access points not seen in two consecutive scans, or not seen in the past four minutes, are dropped from the list. When the WiFi network selection UI is open, scans happen more frequently, reducing this window to around 20-30 seconds.
Enterprise WiFi: 802.1X and nm-applet
Enterprise WPA2-Enterprise networks using EAP methods (PEAP, TTLS, TLS) require additional configuration that the nm-applet GUI exposes through its connection editor. The key fields are the EAP method, inner authentication protocol, identity, password or certificate path, and CA certificate.
When using the iwd backend, there is a critical constraint: NetworkManager cannot auto-generate 802.1X provisioning files for iwd. You must write the provisioning file manually to /var/lib/iwd/essid.8021x. A PEAP/MSCHAPv2 example:
[Security] EAP-Method=PEAP EAP-Identity=[email protected] EAP-Password=yourpassword EAP-CACert=/etc/ssl/certs/ca-bundle.crt EAP-Phase2-Method=MSCHAPV2 [Settings] AutoConnect=true
With wpa_supplicant as the backend, NetworkManager can generate and manage these profiles through nm-applet's connection editor without manual file writing. For environments with complex EAP configurations, wpa_supplicant remains the more complete choice.
Wrapping Up
Linux WiFi through a GTK interface is a layered system, and problems in any layer produce nearly identical symptoms at the top. Understanding that nm-applet is a GTK 3 process talking exclusively to NetworkManager over D-Bus, that it depends on libnma (not libnma-gtk4) for its dialogs, that it ships two tray protocols and since 1.32.0 auto-selects AppIndicator/SNI outside X11, and that NetworkManager itself delegates authentication to either wpa_supplicant or iwd -- that understanding transforms opaque failures into diagnosable problems.
The practical takeaways: on GNOME Shell, nm-applet is not the right tool -- use nm-connection-editor for advanced profile editing and let the Shell panel handle status; on other desktops and window managers, nm-applet is the correct choice. On Wayland sessions, nm-applet 1.32+ with AppIndicator support compiled in should work automatically; if it doesn't, the explicit --indicator flag is the reliable fallback. Install a standalone systray for bare window managers. When a WiFi device is completely absent from NetworkManager, start at the kernel: check whether the driver is loaded with lspci -k and whether firmware is installed before assuming any higher-layer problem. Use journalctl -u NetworkManager -f and nmcli general logging level DEBUG domains WIFI to diagnose failures that survive the tray-level checklist. Keep only one network management service active at a time; check rfkill if the interface exists but won't connect; and prefer nmcli or nmtui when the GTK layer is unavailable or misbehaving. For MAC randomization, stable-ssid is the practical middle ground -- better privacy than permanent, fewer captive-portal headaches than random. The current NM daemon is 1.54; if your distro ships anything older than 1.52.2, check for the CVE-2025-9615 security patch. For minimal setups, iwd is leaner, but enterprise environments should stick with wpa_supplicant until the iwd provisioning file workflow is familiar.
Sources: Arch Wiki: NetworkManager; BLFS: network-manager-applet; Ubuntu manpages: nm-applet(1); Dan Williams / GNOME Blog: NetworkManager; NetworkManager 1.54 release blog; NetworkManager 1.48 release blog; Gentoo Wiki: NetworkManager; Debian Wiki: NetworkManager/iwd; Debian Changelog: network-manager-applet; Debian Packages: libnma-gtk4-dev; Elmord's blog: almost-wayland; NM upstream: CVE-2025-9615 fix.