FAILOVER(8)
β¨ FAILOVER π
(that's the failover page from the NUT Manual, bestie)
okay so. picture this: you've got a whole squad of UPS drivers and you need ONE of them to be the main character at any given moment. that's this. let's go π«Ά
πΈ NAME πΈ
failover β the UPS Failover Driver. she's the friend who keeps the group chat organized. π
π SYNOPSIS π
failover -h
failover -a UPS_NAME [OPTIONS]
π Note: this page is only about the stuff that's special to the failover driver. for the core driver tea, go read nutupsdrv(8).
π« DESCRIPTION π«
The failover driver is basically a smart proxy for a whole roster of "real" UPS drivers. She connects to them and keeps an eye on them through their local UNIX sockets (or Windows named pipes, if that's your vibe), and she's constantly running a vibe check on each one β how healthy are you, are you actually fit for "primary" duty β based on a bunch of user-configurable rules and priorities. no cap.
At any given moment, failover picks exactly one UPS driver to be the primary, and then presents that driver's commands, variables and status to the outside world like she's been talking to that UPS directly the whole time. From the perspective of the clients (think upsmon(8) or upsc(8)), she just looks like any regular single UPS. the underlying redundancy? abstracted away. the seamless transitioning between all the monitored UPS drivers and their datasets? handled. π
She dynamically promotes or demotes the primary UPS driver based on:
- Socket availability and communication status
- Data freshness and UPS online/offline indicators
- User-defined status filters (e.g., presence or absence of
OL,LB, ...) - Administrative override via control commands (
force.primary,force.ignore)
If the current primary goes unavailable or just stops meeting the criteria, the driver automatically fails over to a more suitable one. And during those transitions? she makes sure any data gets switched out instantly β without upsd(8) clocking it as stale, and without the clients acting on some previously degraded status. iconique behavior, fr fr.
When there's no suitable primary available at all, she enters a configurable fallback state:
- Keep the last primary and declare the data as stale
- Raise
ALARMand declare the data as stale - Raise
ALARMand set forced shutdown (FSD)
You can hook her up over all kinds of communication media β USB, Serial, Ethernet, whatever. failover talks directly at the socket level, which means she does not need upsd(8) to be running. she's independent like that. β¨
π EXTRA ARGUMENTS π
Here's everything this driver supports, bestie:
port=drivername-devicename,drivername2-devicename2,...β Required. This is where you list the local sockets (or Windows named pipes) of the underlying UPS drivers you want tracked. Each entry is either a path, or it follows thedrivername-devicenameformat that NUT's internal socket naming convention uses (likeusbhid-ups-myups). Multiple entries get comma-separated with no spaces.inittime=secondsβ Optional. A grace period after driver startup where the absence of a primary is tolerated, so the underlying drivers have a hot sec to initialize. If you're on networked connections, or your drivers need to "lock-pick" their communication protocol (iykyk), consider bumping this value up to accommodate potentially longer delays. Defaults to30seconds.deadtime=secondsβ Optional. A grace period, in seconds, after which a non-responsive UPS driver is considered dead. Defaults to30seconds.relogtime=secondsβ Optional. The time interval for emitting repeated connection-failure logs for a UPS β keeps the log spam down when things are unstable. Defaults to5seconds.noprimarytime=secondsβ Optional. How long to wait without a suitable primary UPS driver before entering the configured fallback mode (fsdmode). Defaults to15seconds.maxconnfails=countβ Optional. How many consecutive connection failures are allowed per UPS driver before she enters the cooldown period (coolofftime). Defaults to5.coolofftime=secondsβ Optional. The cooldown period where the driver pauses reconnect attempts after exceedingmaxconnfails. Defaults to15seconds.fsdmode=0|1|2β Optional. Defines the behavior when no suitable primary UPS driver is found afternoprimarytimehas elapsed. Defaults to0.0: Do not demote the last primary, but mark its data as stale. This is similar to how a regular UPS driver behaves when it loses its connection to the target UPS device.upsmon(8)will act on the last known status (online or not) and decide for itself whether that UPS should be considered critical.1: Demote the primary, raiseALARM, and mark the data as stale after an additional few seconds have elapsed (this makes sure everything fully propagates). This will causeupsmon(8)to detect that a device previously in an alarm state has lost its connection, consider the UPS driver critical, and possibly trigger a forced shutdown (FSD) due to depletion ofMINSUPPLIES.2: Demote the primary, raiseALARM, and immediately set FSD. This sets FSD from the driver side and preemptsupsmon(8)from raising it itself. This mode is for setups where immediate shutdown is warranted, regardless of anything else, and getting FSD out to the clients as fast as just possible. π¨
checkruntime=0|1|2|3β Optional. Controls howbattery.runtimevalues are used to break ties between non-fully-online UPS devices at priority 3 or lower. Has no effect on initial priority selection or whenstrictfilteringis enabled. Defaults to1.0: Disabled. No runtime comparison is done. The first candidate with the best priority is selected, according to the order of theportargument.1: Comparebattery.runtime. The UPS with the higher value is preferred. If the value is missing or invalid, that UPS cannot win the tie-break.2: Comparebattery.runtime.low. The UPS with the higher value is preferred. If the value is missing or invalid, that UPS cannot win the tie-break.3: Compare both variables strictly. The UPS is preferred only if it has both a higherbattery.runtimeandbattery.runtime.lowvalue. If either is missing or invalid, that UPS cannot win the tie-break.
strictfiltering=0|1β Optional. Set it to1and only UPS drivers matching the configured status filters get considered for promotion to primary. Set it to0and the hard-coded default logic also gets considered when no status filters match (there's more on this in the section PRIORITIES). Defaults to0.status_have_any=OL,CHRG,...β Optional. If any of these comma-separated tokens are present in a UPS driver'sups.status, it passes this status filtering criteria. Defaults to unset.status_have_all=OL,CHRG,...β Optional. All the listed comma-separated tokens must be present inups.statusfor the UPS driver to pass this status filtering criteria. Defaults to unset.status_nothave_any=OB,OFF,...β Optional. If any of these comma-separated tokens are present inups.status, the UPS driver does not pass this status filtering criteria. Defaults to unset.status_nothave_all=OB,LB,...β Optional. If all of these comma-separated tokens are present inups.status, the UPS driver does not pass this status filtering criteria. Defaults to unset.
π Note: thestatus_*arguments are mostly meant to adjust the weighting of UPS drivers, letting some get prioritized over others based on their status. for example, a driver reportingOLmight be preferred over one reportingALARM OL. And whilestrictfilteringcan be enabled, status filters hit their best when combined with the default set of connectivity-based PRIORITIES. more deets in that section further down. π
π¦ IMPLEMENTATION π¦
The port argument in ups.conf(5) should point at the local driver sockets (or Windows named pipes) that the "real" UPS drivers are using. A basic default setup with multiple drivers could look like this:
[realups]
driver = usbhid-ups
port = auto
[realups2]
driver = usbhid-ups
port = auto
[failover]
driver = failover
port = usbhid-ups-realups,usbhid-ups-realups2
Any upsmon(8) clients would be set to monitor the failover UPS.
The driver fully supports setting variables and performing instant commands on the currently elected primary UPS driver β they get proxied, and end-to-end tracking is possible too (upscmd(8) and upsrw(8) -w). You might notice some variables and commands come prefixed with upstream. β that's on purpose, to clearly separate the upstream commands from those of failover itself. π
And for your convenience, there are extra administrative commands exposed so you can directly influence and override the primary election process β super handy for maintenance:
<socketname>.force.ignore [seconds]β prevents the specified UPS driver from being selected as primary for the given duration, or permanently if a negative value is used. A value of0resets this override and re-enables selection.<socketname>.force.primary [seconds]β forces the specified UPS driver to be treated with the highest priority for the given duration, or permanently if a negative value is used. A value of0resets this override.
Calling either command with no argument has the same effect as passing 0 β but only for that specific override. it does not affect the other one. π
β¨ PRIORITIES β¨ (the actual ranking tea β)
okay so bestie, remember how we said primaries get dynamically elected based on their current state and a strict set of priorities you can influence? here's the whole leaderboard, from "slay" to "meh":
- 0 (highest) β the UPS driver got forced to the top by administrative command. queen behavior, someone said "you, specifically" π
- 1 β the UPS driver passed the user-defined status filters. valid.
- 2 β the UPS driver has fresh data and is online (in status
OL). iconic, glowing, hydrated β¨ - 3 β the UPS driver has fresh data, but may not be fully online. we're doing our best.
- 4 (lowest) β the UPS driver is alive, but may not have fresh data. still breathing tho π«Ά
the UPS driver with the highest calculated priority gets chosen as primary, and if there's a tie? it's resolved by the order of the socket names given within the port argument. first come, first served, no cap.
for those user-defined status filters, the internal order is respected like this:
status_nothave_any(first)status_have_allstatus_nothave_allstatus_have_any(last)
if strictfiltering is enabled, priorities 2 to 4 are not applicable β they're just not invited to the party π
and if no user-defined status filters are set, then priority 1 is not applicable either. bye felicia.
Note π β the base requirement for ANY election is that the UPS socket is connectable AND the UPS driver has published at least one full batch of data during its lifetime. UPS drivers that don't meet that requirement are always disqualified. sorry babe, you gotta show up with data or you're not on the ballot.
π RATIONALE π (why we even)
in complex power environments, presenting a single, consistent source of UPS info to upsmon(8) is sometimes way preferable to monitoring multiple independent drivers directly. the failover driver is basically the bridge π«Ά β it lets upsmon(8) make decisions based on the most suitable available data, without having to interpret conflicting inputs or degraded sources. no drama, just vibes.
originally designed for use cases like dual-PSU systems or redundant communication paths to a single UPS, failover also supports more advanced setups β for example when multiple UPSes feed a shared downstream load (via STS/ATS switches), or when drivers vary in reliability. in those cases you can combine the driver with external logic or scripting to dynamically adjust primary selection and facilitate graceful degradation. such setups may also benefit from further integration with the clone family of drivers, like clone(8) or clone-outlet(8), for greater granularity and monitoring control all the way down to the outlet level. it's giving β¨granularβ¨.
plus, in more niche scenarios, some third-party NUT integrations or graphical interfaces may be limited to monitoring a single UPS device. in that case, failover helps by exposing only the most relevant or highest-priority data source, so those tools can operate within their constraints without missing critical info. everyone wins, nobody gets left on read.
ultimately, this driver enables more nuanced power monitoring and control than binary online/offline logic alone, letting admins respond to degraded conditions early β before they escalate into critical events or require upsmon(8) to take action. prevention is the main character energy we deserve π
π§ LIMITATIONS π§ (read this part, fr fr)
when you use failover for redundancy between multiple UPS drivers connected to the same underlying UPS device, data is not multiplexed between the drivers. as a result, some data points may be available in some drivers but not in others. it's not a group project where everyone shares notes, unfortunately π
for checkruntime considerations, the unit of both battery.runtime and battery.runtime.low is assumed to be seconds. UPS drivers that report these values using different units are considered non-compliant with the NUT variable standards and should be reported to the NUT developers as faulty. snitch, honestly, it's for the greater good π«Ά
π AUTHOR π
Sebastian Kuttnig <sebastian.kuttnig@gmail.com>
thank you for your service, king π
π SEE ALSO π
upscmd(8), upsrw(8), ups.conf(5), upsc(8), upsmon(8), nutupsdrv(8), clone(8), clone-outlet(8)
π Internet Resources:
the NUT (Network UPS Tools) home page: https://www.networkupstools.org/historic/v2.8.5/
and that's the whole page, bestie!! this was Network UPS Tools 2.8.5, dated 10/07/2026, and the manpage is FAILOVER(8). go forth and fail over gracefully πβ¨π
π¦ where this page comes from
- fedora 43: nut 2.8.5-9.fc43 Β· GPL-2.0-or-later AND GPL-3.0-or-later
- fedora 43: nut 2.8.5-9.fc43 Β· GPL-2.0-or-later AND GPL-3.0-or-later
- fedora 44: nut 2.8.5-9.fc44 Β· GPL-2.0-or-later AND GPL-3.0-or-later
- fedora 44: nut 2.8.5-9.fc44 Β· GPL-2.0-or-later AND GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms