UPS HOWTO: safe shutdown with NUT and apcupsd on Linux
A UPS only protects your data if the computer knows when the battery is running out and shuts down cleanly before it does. On Linux that job belongs to Network UPS Tools (NUT), which supports most brands and can shut down a whole rack from one UPS, or to apcupsd for APC units. This page sets up NUT step by step and tests it.
The classic UPS-HOWTO (cables, home-made powerd scripts; last revised in 2007) is kept by the Linux Documentation Project at tldp.org. Today almost every UPS has a USB or network port, and you should not need to build a cable.
NUT or apcupsd?
| Network UPS Tools | apcupsd | |
|---|---|---|
| Hardware | Most brands; usbhid-ups covers any USB UPS that follows the HID Power Device class (APC, CyberPower, Eaton, Tripp Lite and others) | APC only |
| Current version | 2.8.5 (April 7, 2026), actively developed; EPEL 9 and 10 ship 2.8.2 | 3.14.14, still packaged (Debian 13) but no new releases in years |
| Several computers on one UPS | Yes, primary/secondary over TCP port 3493 | Yes, through its network server on port 3551 |
| Config directory | /etc/nut/ (Debian, Ubuntu, Arch); /etc/ups/ (Fedora, RHEL) | /etc/apcupsd/ |
Use NUT unless you already run apcupsd happily. Run only one of the two: both want exclusive access to the UPS.
How a safe shutdown works
- The driver (for example
usbhid-ups) talks to the UPS and publishes its status:OL(on line),OB(on battery),LB(low battery),RB(replace battery),CHRGand others. - upsd serves that data to clients on TCP port 3493.
- upsmon runs on every protected computer. When the UPS is OB and LB, the primary (the machine attached to the UPS) sets the forced-shutdown flag FSD, waits up to HOSTSYNC (15 seconds by default) for the secondaries to log out, waits FINALDELAY (5 seconds), then runs SHUTDOWNCMD.
- During shutdown, upsmon creates the POWERDOWNFLAG file. At the very end of shutdown, NUT's systemd hook (
/usr/lib/systemd/system-shutdown/nutshutdown) sees the flag and runsupsdrvctl shutdown, which tells the UPS to switch its outlets off after a delay (offdelay, 20 seconds by default forusbhid-ups). - When mains power returns, the UPS turns the outlets back on (after
ondelay, 30 seconds by default) and the computer boots, provided its firmware is set to power on after AC loss.
Step 4 matters: if the UPS never switches off, a computer that shut down during a long outage stays off even when power comes back.
Set up NUT for one computer and a USB UPS
1. Install and find the UPS
sudo apt install nut # Debian, Ubuntu (nut-server + nut-client)
sudo dnf install nut nut-client # Fedora, RHEL (EPEL)
sudo pacman -S nut # Arch
sudo nut-scanner -U
nut-scanner -U lists USB devices NUT can drive and prints a ready-made ups.conf section with the driver, port and vendor/product IDs. The paths below are for Debian, Ubuntu and Arch; on Fedora and RHEL the same files live in /etc/ups/.
2. Describe the UPS: ups.conf
# /etc/nut/ups.conf (Fedora/RHEL: /etc/ups/ups.conf)
[myups]
driver = usbhid-ups
port = auto
desc = "Office server UPS"
For USB the port value is ignored but must be present. With two identical UPS units, add serial = ... (from nut-scanner) so each section matches the right one.
3. Create the monitoring user: upsd.users
# /etc/nut/upsd.users
[upsmon]
password = <upsmon-password>
upsmon primary
4. Tell upsmon what to watch: upsmon.conf
# /etc/nut/upsmon.conf (keep the other lines of the packaged file)
MONITOR myups@localhost 1 upsmon <upsmon-password> primary
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
POWERDOWNFLAG /etc/killpower
The fields of MONITOR are the UPS (name@host), how many power supplies of this machine it feeds, the user name and password from upsd.users, and the role. upsmon has no built-in default for POWERDOWNFLAG; keep the path your package's sample file uses if it sets one.
5. Set the mode and start
# /etc/nut/nut.conf
MODE=standalone
sudo chmod 640 /etc/nut/upsd.users /etc/nut/upsmon.conf
sudo upsdrvsvcctl resync # create a driver service for each ups.conf section
sudo systemctl enable --now nut-server.service nut-monitor.service
Debian ships MODE=none, which keeps NUT from starting at all until you change it.
6. Check that it works
upsc -l # list UPS names
upsc myups # all variables
upsc myups ups.status # OL when on mains
upsc myups battery.charge
upsc myups battery.runtime # seconds
journalctl -u nut-monitor -b
Pull the UPS's mains plug for a minute: ups.status should change to OB DISCHRG and every logged-in user gets a wall message. Plug it back in before the battery runs low.
Several computers on one UPS
On the primary (the machine with the USB cable), set MODE=netserver in nut.conf and tell upsd where to listen in upsd.conf; by default it binds only to 127.0.0.1 and ::1:
# /etc/nut/upsd.conf
LISTEN 127.0.0.1 3493
LISTEN 192.168.1.10 3493
Add a second user for the clients in upsd.users:
[monuser]
password = <monuser-password>
upsmon secondary
Open TCP port 3493 on the primary's firewall for those clients only. On each client, install the client package (nut-client), set MODE=netclient, and add:
MONITOR myups@192.168.1.10 1 monuser <monuser-password> secondary
Then sudo systemctl enable --now nut-monitor.service and check with upsc myups@192.168.1.10. A machine with two power supplies on different UPS units uses a powervalue of 1 on each MONITOR line and MINSUPPLIES 1, so it keeps running while either UPS has power.
Test the full shutdown
This really shuts down. upsmon -c fsd sets forced shutdown: every secondary and then the primary powers off, and the UPS switches its outlets off. Do it in a maintenance window, with everyone warned.
sudo upsmon -c fsd
Watch that secondaries go down first, the primary follows, the UPS outlets switch off, and everything comes back by itself when the UPS turns on again. If machines stay off, enable "Restore on AC power loss" (the name varies) in each machine's firmware setup.
apcupsd for APC units
sudo apt install apcupsd
For a USB-connected APC UPS, the important lines in /etc/apcupsd/apcupsd.conf are:
UPSCABLE usb
UPSTYPE usb
DEVICE
BATTERYLEVEL 5
MINUTES 3
TIMEOUT 0
Leave DEVICE empty for USB. apcupsd starts a shutdown at whichever comes first: charge below BATTERYLEVEL percent, estimated runtime below MINUTES, or TIMEOUT seconds on battery (0 turns that one off). The defaults shown are 5 percent and 3 minutes; raise them for a server that needs longer to stop its services. Restart with sudo systemctl restart apcupsd and check with apcaccess status, which shows STATUS, BCHARGE, TIMELEFT and LOADPCT among others. Other machines can follow it with UPSTYPE net and DEVICE server:3551.
Common mistakes
- Never testing. A UPS set-up that has not been through one full test usually fails the first real outage.
- Thresholds too tight. Old batteries give far less runtime than the label. Leave a margin, and replace batteries when the UPS reports
RB. - Two daemons on one UPS, or the desktop's own power manager fighting NUT for the USB device.
- Passwords readable by all:
upsd.usersandupsmon.confshould be mode 640, groupnut. - Forgetting the network gear. If the switch between primary and secondaries is not on the UPS, secondaries lose contact and may shut down early, or not hear the FSD at all.
Sources
- Network UPS Tools home page (release 2.8.5)
- ups.conf(5), NUT
- usbhid-ups(8), NUT
- upsd.users(5), NUT
- upsd.conf(5), NUT
- upsmon.conf(5), NUT
- upsmon(8), NUT
- upsc(8), NUT
- nut.conf(5), NUT
- nut-scanner(8), NUT
- nut-driver-enumerator(8) and upsdrvsvcctl, NUT
- UPS status values, NUT developer guide
- nutshutdown systemd hook, NUT source
- nut package versions in Fedora and EPEL, Fedora Packages
- Fedora nut package spec (/etc/ups)
- nut package in Arch Linux (/etc/nut)
- apcupsd package in Debian 13
- apcupsd.conf(5), Debian 13
- apcaccess(8), Debian 13
- The UPS HOWTO (classic), Linux Documentation Project