If you've ever come home to a Proxmox host that rebooted mid-write because the power blinked out for four seconds, you already know why this topic matters. VMs don't shut down cleanly when the plug is pulled. Neither do LXC containers, and neither does your ZFS pool if it's mid-transaction. A cheap UPS keeps the lights on for a few minutes, but a few minutes only helps if something on the Proxmox side actually knows the power is gone and reacts to it.
That's the job of Network UPS Tools, usually just called NUT. It's not a Proxmox feature exactly — it's a Debian package, and Proxmox VE 9.x runs on Debian 13 (Trixie), so it installs and behaves the same way it would on any Debian box. This guide walks through wiring a USB-connected UPS into your Proxmox host so it shuts down gracefully instead of just dying.
What You Will Learn
By the end of this article you'll have a Proxmox VE host that detects when it's running on battery power and shuts itself down safely before the battery runs out. Specifically, you'll learn:
- What NUT actually is and how its pieces fit together
- How to install and configure NUT directly on a Proxmox VE host with a USB-connected UPS
- How to test the setup without actually pulling the plug
- How to extend shutdown behavior to VMs and containers, not just the host
- What to do when NUT can't see your UPS, or sees it but won't shut anything down
This guide assumes a single Proxmox VE host with a UPS plugged into it over USB — by far the most common homelab setup. Network-connected (SNMP) UPS units and cluster-wide shutdown coordination are mentioned briefly near the end, but they're a bigger topic on their own.
What Is This Feature?
Network UPS Tools is an open source project that talks to UPS hardware and exposes its status — battery charge, whether it's on line power or battery power, estimated runtime — to anything on the system that asks. It's been around since the late 1990s and supports an enormous range of UPS brands: APC, CyberPower, Eaton, Tripp Lite, and dozens of smaller manufacturers. NUT is made of three cooperating pieces, and understanding them makes the config files a lot less confusing later:
- upsd (the driver) — a small program that speaks the UPS's specific protocol, whether that's USB HID, a serial cable, or SNMP over the network. It reads raw status from the hardware.
- upsd (the server) — sits between the driver and everything else, and answers status queries over a local TCP port (3493 by default).
- upsmon (the monitor) — watches upsd, decides when battery power has gone on too long, and triggers the actual shutdown.
Yes, the driver and the server share a similar name in casual conversation even though the binaries are different (the driver is usually something like usbhid-ups). Don't worry about memorizing that — the install process creates all three for you, you're just filling in config files.
Why Would You Use It?
A UPS without any host-side integration is really just an oversized surge protector with a battery in it. It'll keep your server running through a short outage, but if the outage outlasts the battery, the host just loses power and goes down hard — same as if there were no UPS at all. Here's what NUT actually buys you:
- Clean shutdowns. ZFS, in particular, doesn't love unclean power loss. It's designed to survive it thanks to copy-on-write semantics, but a proper
shutdown -his still safer than yanking the cord, and it avoids a lengthy scrub or resilver afterward. - No corrupted VM disks. A Windows VM that's mid-write to its virtual disk when power dies can end up needing a chkdsk, or worse. Guest agents get a chance to flush and shut down cleanly instead.
- You find out about outages you'd otherwise miss. NUT can email or log every time it goes on battery, so you know your power blinked at 3 a.m. even if nothing actually went down.
Honestly, if you're running Proxmox on a single box in a closet with no UPS at all, buying one and setting up NUT is one of the highest-value hours you can spend on a homelab. It's the kind of thing you don't appreciate until the one time it saves a VM disk.
Prerequisites
Before starting, make sure you have:
- A Proxmox VE host, version 8.x or 9.x (this guide was tested on Proxmox VE 9.2, running on Debian 13)
- A UPS connected to the host over USB — most consumer and small-business UPS units include a USB cable for exactly this purpose
- Root shell access to the host, either through the web UI's Shell console or SSH
- About 20 minutes
Check that Proxmox can actually see the UPS at the USB level before touching NUT at all. Run:
lsusb
You're looking for a line that names your UPS manufacturer — something like American Power Conversion Back-UPS or CyberPower. If nothing shows up, it's a cabling or hardware problem, not a NUT problem, and no amount of config editing will fix it. Try a different USB port or cable first.
Step-by-Step Tutorial
Step 1: Install NUT
Update your package list and install the nut package. This pulls in the driver binaries, the server, and the monitor as one package on Debian:
apt update
apt install nut
This installs in a few seconds — it's a small package, well under 5 MB with dependencies.
Step 2: Set the operating mode
Open /etc/nut/nut.conf and set the mode. Since the UPS is plugged directly into this host and this host is the only thing that needs to know about it, use standalone:
MODE=standalone
The other modes (netserver, netclient) matter when one machine hosts the UPS and other machines on the network need to hear about outages too. Skip those for now — standalone is correct for a single Proxmox host.
Step 3: Identify your UPS driver
Run the driver detection tool to figure out which driver your specific UPS needs:
nut-scanner -U
For most USB UPS units this returns a block naming the usbhid-ups driver along with the vendor and product IDs. Older or serial-connected units may need a different driver name — the NUT hardware compatibility list on networkupstools.org covers the full range if usbhid-ups doesn't match.
Step 4: Configure the driver in ups.conf
Edit /etc/nut/ups.conf and add a section for your UPS. Give it a short name — you'll use this name everywhere else, so keep it simple:
[apc1]
driver = usbhid-ups
port = auto
desc = "Rack UPS in the server closet"
port = auto is correct for USB HID devices — the driver finds the device itself rather than needing a fixed device path. The name in brackets (apc1 here) is arbitrary; pick something that means something to you if you ever add a second UPS.
Step 5: Configure the server user in upsd.users
NUT's monitor process needs to authenticate to the server, even when they're both running on the same box. Edit /etc/nut/upsd.users and add:
[monmaster]
password = ChangeThisPassword
upsmon master
Pick a real password here — this file is only readable by root, but there's no reason to leave a placeholder in place. The upsmon master line grants this user permission to actually trigger a shutdown, as opposed to just reading status.
Step 6: Point upsd at the UPS in upsd.conf
For a standalone setup with no remote clients, the default /etc/nut/upsd.conf usually needs no changes. If you want to restrict which addresses can query the server, you can add a LISTEN line, but leaving it at the default (listening on localhost and the local network interface) is fine for a single host.
Step 7: Configure the shutdown behavior in upsmon.conf
This is the file that actually decides when to shut the host down. Edit /etc/nut/upsmon.conf and set the MONITOR line to match the UPS name and user from steps 4 and 5:
MONITOR apc1@localhost 1 monmaster ChangeThisPassword master
Then set the shutdown command near the bottom of the file:
SHUTDOWNCMD "/sbin/shutdown -h +0"
There's also a FINALDELAY setting, which controls how long upsmon waits after deciding to shut down before it actually runs the shutdown command — the default of a few seconds is fine for most setups.
Step 8: Start the services
Restart both the server and the monitor so they pick up your changes:
systemctl restart nut-server
systemctl restart nut-monitor
systemctl enable nut-server nut-monitor
The enable command makes sure both services come back up automatically after a reboot — easy to forget, and without it your carefully configured UPS monitoring silently stops working the next time you patch and reboot the host.
Step 9: Confirm it's working
Query the UPS status directly:
upsc apc1@localhost
You should get back a list of variables: battery.charge, ups.status, battery.runtime, and so on. If ups.status reads OL (online), the UPS is on line power and everything's reporting correctly.
Commands Explained
| Command | What it does |
|---|---|
lsusb | Lists USB devices connected to the host, used to confirm the UPS is visible at the hardware level before configuring NUT. |
nut-scanner -U | Probes connected USB devices and suggests the correct NUT driver and configuration block for each one it recognizes. |
upsc <upsname>@localhost | Queries the NUT server for the current status of a named UPS — battery charge, online/battery state, runtime estimate, and more. |
upscmd | Sends instant commands to a UPS driver that supports them, such as a test alarm. Requires a user with the instcmds permission in upsd.users. |
systemctl restart nut-server | Restarts the NUT server process so it picks up changes to ups.conf or upsd.conf. |
systemctl restart nut-monitor | Restarts the monitor process so it picks up changes to upsmon.conf, including new MONITOR lines or a changed shutdown command. |
Common Errors
A few messages come up often enough that they're worth calling out by name.
"Driver not connected" when you run upsc — the server is up, but the driver process isn't talking to it. Almost always this means the driver crashed on start because it couldn't open the USB device, often because another process (sometimes a leftover apcupsd install) already has it open.
"Connection failure: Connection refused" — the NUT server (upsd) isn't running at all. Check systemctl status nut-server and look at the bottom of the output for the actual error, rather than guessing.
"Access denied" from upsmon — the username or password in upsmon.conf's MONITOR line doesn't match what's in upsd.users, or the password has a typo. These two files have to agree exactly; NUT won't tell you which field is wrong, just that authentication failed.
Troubleshooting
If lsusb doesn't show your UPS at all, stop troubleshooting NUT and check the cable. USB cables that ship with cheap UPS units are notoriously unreliable — swap it for a known-good one before assuming there's a software problem.
If nut-scanner finds the device but upsc still reports no driver connected, check whether the driver actually started:
systemctl status nut-driver-enumerator
On Debian-based systems, the individual driver processes are launched by nut-driver-enumerator based on what's in ups.conf, not started directly by systemctl. If you edited ups.conf after the services were already running, a restart of nut-server is usually enough to pick up the new driver, but a full systemctl restart nut-driver-enumerator nut-server is worth trying if it still doesn't show up.
If everything reports fine but you're not confident the shutdown will actually trigger, you can test it safely without pulling the real plug — most UPS units let you simulate a power event by holding the test button, which briefly switches the UPS to battery mode. Watch upsc apc1@localhost during the test; ups.status should flip from OL to OB (on battery) within a few seconds.
Best Practices
Don't set the shutdown to trigger the instant the UPS goes on battery. Momentary power blips that last a second or two shouldn't take your whole host down — that's usually controlled by how long upsmon waits before acting, combined with your UPS's own low-battery threshold. Tune this to your UPS's actual runtime rather than leaving defaults untouched.
If you're running VMs with the QEMU guest agent installed, they'll respond to an ACPI shutdown signal cleanly when the host shuts down — worth confirming that's enabled on anything important, since a host-level shutdown doesn't automatically mean every guest shuts down gracefully on its own.
Set up email notifications for power events, separate from the shutdown behavior itself. Knowing your power flickered at 2 a.m. even when the battery covered it fine is useful information — it might be the first sign of a failing UPS battery or a building electrical issue worth having looked at.
If you eventually move to a Proxmox VE cluster, be aware that standalone NUT on one node only protects that node. A shared UPS protecting multiple hosts is a genuinely more involved setup involving a netserver/netclient split, and it's worth getting comfortable with single-host NUT first before taking that on.
Frequently Asked Questions
Does Proxmox VE have built-in UPS support?
Not through the web GUI. NUT is a standard Debian package that runs alongside Proxmox on the same host — there's no dedicated Proxmox UPS menu, you're configuring plain NUT config files.
What if my UPS connects over the network instead of USB (SNMP)?
You'd use the snmp-ups driver instead of usbhid-ups in ups.conf, pointing at the UPS's management IP and community string. The rest of the setup — upsd.users, upsmon.conf, and the shutdown command — stays the same.
Will this shut down my VMs and containers too, or just the host?
A host shutdown initiated by shutdown -h does send ACPI shutdown signals to running VMs and stop LXC containers as part of Proxmox's normal shutdown sequence. Guests with the QEMU guest agent respond fastest and most cleanly; guests without it may just get powered off if they don't react in time.
Just be aware that FINALDELAY and any shutdown timeout Proxmox itself uses both need to allow enough time for guests to actually finish shutting down before the host cuts power — on a host with a lot of VMs, the default delay might not be long enough.
Can I run NUT in a VM instead of directly on the Proxmox host?
You can, but it defeats part of the purpose for USB-connected UPS units — the VM would need the USB device passed through, and if the host itself needs to shut down, having the monitoring logic live inside a guest adds a layer of indirection that isn't necessary for a single host. It makes more sense for network/SNMP UPS setups where multiple machines share one UPS.
How much battery runtime do I actually need?
Enough to survive your shutdown time plus a safety margin — for a single Proxmox host with a handful of VMs, five to ten minutes of runtime is typically more than enough, since a clean shutdown usually completes in well under a minute once triggered.
Conclusion
None of this is complicated once the pieces click — a driver that talks to the hardware, a server that shares that status locally, and a monitor that decides when enough is enough and pulls the shutdown trigger. The whole setup takes maybe twenty minutes, and it's the kind of thing that sits quietly doing nothing for months until the one night it matters. If you've got a UPS sitting under your desk that's never been wired into anything, this is worth doing today rather than after the next outage teaches you the hard way.