This version of the page reflects NUT release v2.8.1 with codebase commited 4ba352d8f at 2023-10-31T21:46:20+01:00
Options, features and capabilities in current development (and future releases) are detailed on the main site and may differ from ones described here.
Since May 2002, this protocol has an official port number from IANA, which is 3493. The old number (3305) was a relic of the original code’s ancestry, and conflicted with other services. Version 0.50.0 and up use 3493 by default.
This protocol runs over TCP. UDP support was dropped in July 2003. It had been deprecated for some time and was only capable of the simplest query commands as authentication is impossible over a UDP socket.
A library, named libupsclient, that implement this protocol is provided in both static and shared version to help the client application development.
Before version 1.5.0, a number of old commands were supported. These have been removed from the specification. For more information, consult an older version of the software.
Multi-word elements are contained within "quotes" for easier parsing. Embedded quotes are escaped with backslashes. Embedded backslashes are also escaped by representing them as \\. This protocol is intended to be interpreted with parseconf (NUT parser) or something similar.
Here’s a table to present the various changes that happened to the NUT network protocol, over the time:
Protocol version | NUT version | Description |
---|---|---|
1.0 | < 1.5.0 | Original protocol (legacy version) |
1.1 | >= 1.5.0 | Original protocol (without old commands) |
1.2 | >= 2.6.4 | Add "LIST CLIENT" and "NETVER" commands |
Add ranges of values for writable variables | ||
1.3 | >= 2.8.0 | Add "cmdparam" to "INSTCMD" |
Add "TRACKING" commands (GET, SET) | ||
Add "PRIMARY" as alias to older "MASTER"
(implementation tested to be backwards
compatible in | ||
Add "PROTVER" as alias to older "NETVER" |
Any new version of the protocol implies an update of NUT_NETVERSION
in configure.ac file.
ERRATA: Earlier revisions of this table mistakenly mentioned LIST CLIENTS
as added since 2.6.4. The actual added command was LIST CLIENT
(no S
)
as documented in its section below.
Retrieve a single response from the server.
Possible sub-commands:
Form:
GET NUMLOGINS <upsname> GET NUMLOGINS su700
Response:
NUMLOGINS <upsname> <value> NUMLOGINS su700 1
<value> is the number of clients which have done LOGIN for this UPS. This is used by the upsmon in primary mode to determine how many clients are still connected when starting the shutdown process.
This replaces the old "REQ NUMLOGINS" command.
Form:
GET UPSDESC <upsname> GET UPSDESC su700
Response:
UPSDESC <upsname> "<description>" UPSDESC su700 "Development box"
<description> is the value of "desc=" from ups.conf for this UPS. If it is not set, upsd will return "Unavailable".
This can be used to provide human-readable descriptions instead of a cryptic "upsname@hostname" string.
Form:
GET VAR <upsname> <varname> GET VAR su700 ups.status
Response:
VAR <upsname> <varname> "<value>" VAR su700 ups.status "OL"
This replaces the old "REQ" command.
Form:
GET TYPE <upsname> <varname> GET TYPE su700 input.transfer.low
Response:
TYPE <upsname> <varname> <type>... TYPE su700 input.transfer.low ENUM
<type> can be several values, and multiple words may be returned:
ENUM, STRING and RANGE are usually associated with RW, but not always. The default <type>, when omitted, is numeric, so either integer or float. Each driver is then responsible for handling values as either integer or float.
Note that float values are expressed using decimal (base 10) english-based representation, so using a dot, in non-scientific notation. So hexadecimal, exponents, and comma for thousands separator are forbidden. For example: "1200.20" is valid, while "1,200.20" and "1200,20" are invalid.
This replaces the old "VARTYPE" command.
Form:
GET DESC <upsname> <varname> GET DESC su700 ups.status
Response:
DESC <upsname> <varname> "<description>" DESC su700 ups.status "UPS status"
<description> is a string that gives a brief explanation of the named variable. upsd may return "Unavailable" if the file which provides this description is not installed.
Different versions of this file may be used in some situations to provide for localization and internationalization.
This replaces the old "VARDESC" command.
Form:
GET CMDDESC <upsname> <cmdname> GET CMDDESC su700 load.on
Response:
CMDDESC <upsname> <cmdname> "<description>" CMDDESC su700 load.on "Turn on the load immediately"
This is like DESC above, but it applies to the instant commands.
This replaces the old "INSTCMDDESC" command.
Form:
GET TRACKING (activation status of TRACKING) GET TRACKING <id> (execution status of a command / setvar) GET TRACKING 1bd31808-cb49-4aec-9d75-d056e6f018d2
Response:
ON (TRACKING feature is enabled) OFF (TRACKING feature is disabled) PENDING (command execution is pending) SUCCESS (command was successfully executed) ERR UNKNOWN (command execution failed with unknown error) ERR INVALID-ARGUMENT (command execution failed due to missing or invalid argument) ERR FAILED (command execution failed)
The LIST functions all share a common container format. They will return "BEGIN LIST" and then repeat the initial query. The list then follows, with as many lines are necessary to convey it. "END LIST" with the initial query attached then follows.
The formatting may seem a bit redundant, but it makes a different form of client possible. You can send a LIST query and then go off and wait for it to get back to you. When it arrives, you don’t need complicated state machines to remember which list is which.
Form:
LIST UPS
Response:
BEGIN LIST UPS UPS <upsname> "<description>" ... END LIST UPS
BEGIN LIST UPS UPS su700 "Development box" END LIST UPS
<upsname> is a name from ups.conf, and <description> is the value of desc= from ups.conf, if available. It will be set to "Unavailable" otherwise.
This can be used to determine what values of <upsname> are valid before calling other functions on the server. This is also a good way to handle situations where a single upsd supports multiple drivers.
Clients which perform a UPS discovery process may find this useful.
Form:
LIST VAR <upsname> LIST VAR su700
Response:
BEGIN LIST VAR <upsname> VAR <upsname> <varname> "<value>" ... END LIST VAR <upsname>
BEGIN LIST VAR su700 VAR su700 ups.mfr "APC" VAR su700 ups.mfr.date "10/17/96" ... END LIST VAR su700
This replaces the old "LISTVARS" command.
Form:
LIST RW <upsname> LIST RW su700
Response:
BEGIN LIST RW <upsname> RW <upsname> <varname> "<value>" ... END LIST RW <upsname>
BEGIN LIST RW su700 RW su700 output.voltage.nominal "115" RW su700 ups.delay.shutdown "020" ... END LIST RW su700
This replaces the old "LISTRW" command.
Form:
LIST CMD <upsname> LIST CMD su700
Response:
BEGIN LIST CMD <upsname> CMD <upsname> <cmdname> ... END LIST CMD <cmdname>
BEGIN LIST CMD su700 CMD su700 load.on CMD su700 test.panel.start ... END LIST CMD su700
This replaces the old "LISTINSTCMD" command.
Form:
LIST ENUM <upsname> <varname> LIST ENUM su700 input.transfer.low
Response:
BEGIN LIST ENUM <upsname> <varname> ENUM <upsname> <varname> "<value>" ... END LIST ENUM <upsname> <varname>
BEGIN LIST ENUM su700 input.transfer.low ENUM su700 input.transfer.low "103" ENUM su700 input.transfer.low "100" ... END LIST ENUM su700 input.transfer.low
This replaces the old "ENUM" command.
this does not support the old "SELECTED" notation. You must request the current value separately.
Form:
LIST RANGE <upsname> <varname> LIST RANGE su700 input.transfer.low
Response:
BEGIN LIST RANGE <upsname> <varname> RANGE <upsname> <varname> "<min>" "<max>" ... END LIST RANGE <upsname> <varname>
BEGIN LIST RANGE su700 input.transfer.low RANGE su700 input.transfer.low "90" "100" RANGE su700 input.transfer.low "102" "105" ... END LIST RANGE su700 input.transfer.low
Form:
SET VAR <upsname> <varname> "<value>" SET VAR su700 ups.id "My UPS"
Response:
OK (if TRACKING is not enabled) OK TRACKING <id> (if TRACKING is enabled) ERR <message> [<extra>...] (see Error responses)
Form:
INSTCMD <upsname> <cmdname> [<cmdparam>] INSTCMD su700 test.panel.start INSTCMD su700 load.off.delay 120
<cmdparam> is an additional and optional parameter for the command.
Response:
OK (if TRACKING is not enabled) OK TRACKING <id> (if TRACKING is enabled) ERR <message> [<extra>...] (see Error responses)
Form:
LOGOUT
Response:
OK Goodbye (recent versions) Goodbye... (older versions)
Used to disconnect gracefully from the server.
Form:
LOGIN <upsname>
Response:
OK (upon success)
This requires "upsmon secondary" or "upsmon primary" in upsd.users
Use this to log the fact that a system is drawing power from this UPS. The upsmon primary will wait until the count of attached systems reaches 1 — itself. This allows the secondaries to shut down first.
You probably shouldn’t send this command unless you are upsmon, or a upsmon replacement.
This command was renamed in NUT 2.8.0 to "PRIMARY" with the older name "MASTER" kept as deprecated alias for compatibility.
Form:
MASTER <upsname>
Response:
OK MASTER-GRANTED (upon success)
Form:
PRIMARY <upsname>
Response:
OK PRIMARY-GRANTED (upon success)
This requires "upsmon primary" in upsd.users
Previously documented response was just OK
— clients checking
that server reply starts with that keyword would handle all cases.
This function doesn’t do much by itself. It is used by upsmon to make sure that primary-mode functions like FSD are available if necessary.
Form:
FSD <upsname>
Response:
OK FSD-SET (success)
This requires "upsmon primary" in upsd.users, or "FSD" action granted in upsd.users
upsmon in primary mode is the primary user of this function. It sets this "forced shutdown" flag on any UPS when it plans to power it off. This is done so that secondary systems will know about it and shut down before the power disappears.
Setting this flag makes "FSD" appear in a STATUS request for this UPS. Finding "FSD" in a status request should be treated just like a "OB LB".
It should be noted that FSD is currently a latch — once set, there is no way to clear it short of restarting upsd or dropping then re-adding it in the ups.conf. This may cause issues when upsd is running on a system that is not shut down due to the UPS event.
Note also that certain drivers can propagate the "FSD" state declared by the smarter UPSes themselves, e.g. when an UPS is charging after an outage and its battery level is below the "safe for load" threshold configured on the device itself. In this case the device usually does not power up its outlets automatically, but it can be forced by the systems administrator. The rationale behind such FSD during charging allows enough power to be guaranteed for systems to both boot and shut down safely, if the wall power disappears again, trading off prolonged unavailability of the shut down servers for the safety of their data. In such cases, administrators should be ready to disarm their upsmon clients until the batteries are charged, to avoid quick shutdowns of quickly restored servers — but only if they are sure about the wall power being restored for good (e.g. outage was due to maintenance).
Form:
PASSWORD <password>
Response:
OK (upon success)
Sets the password associated with a connection. Used for later authentication for commands that require it.
Form:
USERNAME <username>
Response:
OK (upon success)
Sets the username associated with a connection. This is also used for authentication, specifically in conjunction with the upsd.users file.
Form:
STARTTLS
Response:
OK STARTTLS
This tells upsd to switch to TLS mode internally, so all future communications will be encrypted. You must also change to TLS mode in the client after receiving the OK, or the connection will be useless.
These three are not intended to be used directly by programs. Humans can make use of this program by using telnet or netcat. If you use telnet, make sure you don’t have it set to negotiate extra options. upsd doesn’t speak telnet and will probably misunderstand your first request due to the extra junk in the buffer.
An error response has the following format:
ERR <message> [<extra>...]
<message> is always one element; it never contains spaces. This may be used to allow additional information (<extra>) in the future.
<message> can have the following values:
ACCESS-DENIED
The client’s host and/or authentication details (username, password) are not sufficient to execute the requested command.
UNKNOWN-UPS
The UPS specified in the request is not known to upsd. This usually means that it didn’t match anything in ups.conf.
VAR-NOT-SUPPORTED
The specified UPS doesn’t support the variable in the request.
This is also sent for unrecognized variables which are in a space which is handled by upsd, such as server.*.
CMD-NOT-SUPPORTED
The specified UPS doesn’t support the instant command in the request.
INVALID-ARGUMENT
The client sent an argument to a command which is not recognized or is otherwise invalid in this context. This is typically caused by sending a valid command like GET with an invalid subcommand.
INSTCMD-FAILED
upsd failed to deliver the instant command request to the driver. No further information is available to the client. This typically indicates a dead or broken driver.
SET-FAILED
upsd failed to deliver the set request to the driver. This is just like INSTCMD-FAILED above.
READONLY
The requested variable in a SET command is not writable.
TOO-LONG
The requested value in a SET command is too long.
FEATURE-NOT-SUPPORTED
This instance of upsd does not support the requested feature. This is only used for TLS/SSL mode (STARTTLS) at the moment.
FEATURE-NOT-CONFIGURED
This instance of upsd hasn’t been configured properly to allow the requested feature to operate. This is also limited to STARTTLS for now.
ALREADY-SSL-MODE
TLS/SSL mode is already enabled on this connection, so upsd can’t start it again.
DRIVER-NOT-CONNECTED
upsd can’t perform the requested command, since the driver for that UPS is not connected. This usually means that the driver is not running, or if it is, the ups.conf is misconfigured.
DATA-STALE
upsd is connected to the driver for the UPS, but that driver isn’t providing regular updates or has specifically marked the data as stale. upsd refuses to provide variables on stale units to avoid false readings.
This generally means that the driver is running, but it has lost communications with the hardware. Check the physical connection to the equipment.
ALREADY-LOGGED-IN
The client already sent LOGIN for a UPS and can’t do it again. There is presently a limit of one LOGIN record per connection.
INVALID-PASSWORD
The client sent an invalid PASSWORD — perhaps an empty one.
ALREADY-SET-PASSWORD
The client already set a PASSWORD and can’t set another. This also should never happen with normal NUT clients.
INVALID-USERNAME
The client sent an invalid USERNAME.
ALREADY-SET-USERNAME
The client has already set a USERNAME, and can’t set another. This should never happen with normal NUT clients.
USERNAME-REQUIRED
The requested command requires a username for authentication, but the client hasn’t set one.
PASSWORD-REQUIRED
The requested command requires a passname for authentication, but the client hasn’t set one.
UNKNOWN-COMMAND
upsd doesn’t recognize the requested command.
This can be useful for backwards compatibility with older versions of upsd. Some NUT clients will try GET and fall back on REQ after receiving this response.
INVALID-VALUE
The value specified in the request is not valid. This usually applies to a SET of an ENUM type which is using a value which is not in the list of allowed values.
The LIST commands may be given the ability to handle options some day. For example, "LIST VARS <ups> +DESC" would return the current value like now, but it would also append the description of that variable.