ModemManager

Revision as of 12:29, 25 February 2026 by Manu (talk | contribs) (Create ModemManager page. Add Configuration, Tips and Tricks and Troubleshooting sections.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

ModemManager is a DBus-activated daemon which manages cellular modems (2G, 3G, 4G and 5G) and establishes cellular data connections.[1]

Configuration

It is possible to enable the modem with:

networking.modemmanager.enable = true;

A good rule of thumb is to use NetworkManager as much as possible and rely on ModemManager functionality directly only when necessary (e.g., when having to insert a PIN).

Tips and Tricks

Prevention of WWAN connection on boot

Due concerns related to tracking and privacy, it may be wished to never automatically establish a cellular connection on boot. The custom Serviced service below allows to achieve exactly this goal.

# Ensure that the modem does not establish a cellular connection
# on boot.
systemd.services.NetworkManager-radio-wwan-initial-setup = {
  description = "Disable WWAN radio on first ModemManager start";
  wantedBy = [ "multi-user.target" ];
  before = [ "ModemManager.service" ];
  after = [ "NetworkManager.service" ]; # Wait for NetworkManager
  requires = [ "NetworkManager.service" ]; # Ensure NetworkManager is running

  serviceConfig = {
    Type = "oneshot";
    RemainAfterExit = true; # The service won't run again on successive ModemManager activations (i.e., after the machine resumes from suspend).
    ExecStart = "${pkgs.networkmanager}/bin/nmcli radio wwan off";
  };
};

Note that the cellular connection will retain the state after resuming from suspend. This is intended for scenarios such as changing trains. However, if the intended goal is to never establish a cellular connection on resume as well, then simply remove the `RemainAfterExit` line.

Troubleshooting

Unreliable suspend/resume

Some modems, such as the Fibocom 350-GL, cause the system to automatically wake up from sleep. The behavior is inconsistent: sometimes it happens immediately, but it can also happen a few seconds or minutes after the machine is in suspended. Other times the machine correctly stays in sleep mode and does not wake up. Other times a loop of continuous suspensions and resumes is experienced.

As a workaround to the unreliability of such WWAN modules, the user needs to stop the `ModemManager` service before sleep. At this point, suspend should no longer cause the problems mentioned above. The user needs to restart `ModemManager` once the computer is resumed if they intend to connect to cellular data.

It is possible to automate this behavior by creating tailored Systemd services:

# Stop ModemManager before sleep.target is reached
# due to a bug with the WWAN module, which otherwise
# wakes up the system immediately after suspend.
systemd.services.ModemManager-stop-before-sleep = {
  wantedBy = [ "sleep.target" ];
  before = [ "sleep.target" ];

  serviceConfig = {
    Type = "oneshot";
    ExecStart = "${pkgs.systemd}/bin/systemctl stop ModemManager.service";
  };
};

# Restart ModemManager shortly after resume from suspend.
# This way the modem can be easily enabled within
# the desktop environment's networks' applet or the CLI.
systemd.services.ModemManager-restart-after-resume = {
  description = "Restart ModemManager after resume";
  wantedBy = [ "post-resume.target" ];
  after = [
    "systemd-suspend.service"
    "systemd-hibernate.service"
    "systemd-hybrid-sleep.service"
  ];

  serviceConfig = {
    Type = "oneshot";
    ExecStart = "${pkgs.systemd}/bin/systemctl restart ModemManager.service";
  };
};