Repository navigation
huawei-ups2000: UPS serial comm lockup triggered by 0x2B ReadDevID=0x01 + ObjectID=0x87 (reproducible "Serial port becomes unresponsive" case) #3735
Description
Summary
The huawei-ups2000(8) man page documents that "some malformed commands are known to lock up the serial port", says this was "only a problem during early development", and asks that reproducible lockups be reported. Here is a concrete, real-hardware trigger observed today:
A single Modbus 0x2B (Read Device Identification) request with ReadDevID=0x01 (basic) requesting ObjectID=0x87 (a vendor-specific extended object, the "device list") puts the UPS into the documented total serial lockup. After receiving it, the UPS stops responding to all Modbus RTU traffic — including ordinary input-register reads that succeeded seconds earlier — on both RS-232 and USB. Recovery requires a full UPS power cycle, as described in the man page.
Per the Modbus specification this frame is semantically illegal (basic ReadDevID may only reference objects 0x00–0x02; 0x87 exists only under extended ReadDevID 0x03). The expected failure mode would be an exception response (ILLEGAL DATA VALUE / ILLEGAL DATA ADDRESS) or per-frame silence — not a persistent whole-stack lockup.
This is not a NUT driver bug — drivers/huawei-ups2000.c never sends such a frame (its ident_req correctly uses ReadDevID=0x03). This report is (a) firmware robustness feedback worth forwarding to Huawei, and (b) a concrete trigger for the man page's lockup section.
Hardware / link
- UPS: Huawei UPS2000, 1 kVA class (nominal 1000 VA, battery 2×12 V 9 Ah). Exact model/firmware string unreadable right now — reading it requires the very device-identification exchange that locks the unit (typical model for this configuration is UPS2000-A-1KTTS).
- Link: RS-232 through an XR21V1410 USB-UART dongle, 9600 8N1, slave address 1, Windows host.
- Frames were sent by a small ctypes-based Modbus RTU master (NUT itself was not running); the behaviour is protocol-level, independent of the master implementation.
Reproduction
⚠️ Reproducing this makes the UPS unresponsive on ALL serial interfaces until it is power-cycled (front-panel output off → unplug line power → wait for LCD black → reconnect), as described in the man page.
- Verify normal operation: 0x03 reads of input registers (e.g. 11024 status, 11043 flags, 12003 charge, 12004–12005 runtime, with the +10000 UPS-number offset described in the driver source) succeed repeatedly.
- Send:
01 2B 0E 01 87 <valid CRC-16>— command 0x2B, MEI 0x0E, ReadDevID 0x01, ObjectID 0x87. - The UPS never completes a response. From this point on, every frame (including previously-working 0x03 reads, and a later-corrected
01 2B 0E 03 87 31 75) returns zero bytes.
Exactly two non-0x03 frames were sent before the lockup (both the malformed frame above); nothing else out of the ordinary preceded it.
Attempted revivals, all unsuccessful
- Modbus BREAK + DTR/RTS deassert/assert cycles
- Restarting the USB-UART device (
pnputil /restart-device) - Full disable/enable of the dongle (RS-232 line fully down for ~6 s — equivalent to unplugging from the host side)
- Unplugging/replugging the serial cable at the UPS end
- Sending the driver's correct extended-identification frame
01 2B 0E 03 87 31 75
Communications have stayed locked for several hours so far; the man page's power-cycle procedure is scheduled and expected to restore them.
Suggested actions
- Man page: extend "Serial port becomes unresponsive" with this concrete trigger class (ReadDevID=0x01/0x02 combined with ObjectID ≥ 0x80), since the current text only mentions malformed commands generically and readers have no way to know which frames are poisonous.
- Forward to Huawei: the firmware should answer with a Modbus exception (or ignore the frame) instead of permanently wedging the shared serial stack (RS-232 + USB).
Activity
csc06 commentedon Oct 7, 2026
Follow-up: the man page's power-cycle procedure fully restored communications on this unit — confirming that recovery works for this trigger as well.
After recovery, the correct extended identification exchange (
0x2B / 0x0E / ReadDevID=0x03 / ObjectID=0x87, i.e. the driver's ownident_reqframe) works fine and returns the device list. This confirms:ReadDevID=0x01).UPS2000A(1 kVA, RS-232 via XR21V1410 USB-UART)P1.0-D1.0(ESN withheld.)
Note: V2R1C1SPC50 is the same firmware version already mentioned in #3593 (shutdown-command behaviour), so this firmware build is known to the project — and it exhibits the malformed-frame lockup too.
jimklimov commentedon Oct 7, 2026
CC: @biergaizi
biergaizi commentedon Oct 19, 2026
Nowadays, LLMs have great analytical and writing capabilities, but the LLMs are only as good as the instructions given by their users. This bug report is an excellent demonstration of useless work "solved" by LLM users, who lack any context about the NUT project.
This is a complete misunderstanding of the man page's context. The man page is not asking for just any reproducible lockups for the UPS. Instead, it's only asking for reproducible lockups by the use of the NUT's
huawei_ups2000driver, not just random hardware erratas!Nothing new has been discovered in this bug report. It's a firmware bug discovered by reading the documentation, and reported to the developer who wrote the documentation.
I already found a 100% reproducible raw Modbus command sequence that could create the lockup back in 2021, back when I started implementing the first handshake. This is why the paragraph about "serial port lockup" even exists in the man page. The command sequence was very similar to the example provided in this bug report. If I kept quiet about it, nobody would even think about investigating it.
Of course it never does so, because I found putting other numbers in this field caused serial port lockups! After some try-and-error, I found
0x03was the safe command to issue, and this is why the driver works.From my best knowledge, it's impossible to trigger this hardware bug during normal use. This is the reason that the man page said this was "only a problem during early development"! All Modbus commands are protected by CRC checksum, furthermore, access to the serial port is already privileged.
For this reason. the detail of my finding remained private and never published, I only vaguely described it as a "malformed command", because I thought the detail is not useful for end-users, and it also does not worth my time to document and publish as a developer. I believe I have already done enough of a courtesy to include a recovery procedure for a driver bug that no longer exists, as a precaution against unknown driver bugs (I also said those bugs should be reported).
The manual only invited readers to submit a report for reproducible lockup problems, if such lockup problems are caused by the NUT driver, or can somehow triggered from NUT.
The man page is end-user documentation, not developer documentation. The man page is supposed to be a documentation of the
huawei_ups2000device driver, not to provide a free knowledge base for about the Huawei UPS2000 hardware in general. While it's useful to share more developer information on GitHub, such as by submitting this issue. It's not appropriate to describe the technical detail encountered by every developer in a user manual.When you read a user manual of a Asus or Supermicro motherboard, you won't find any step-by-step instruction to trigger an AMI BIOS or Intel chipset errata on the motherboard (although it may contain a recovery procedure to reset the motherboard in case it occurs, and you may find more information from the Intel website or 3rd-party hardware/gaming). NUT driver man pages should be treated similarly, it should be end-user oriented, not a developer log.
Alternative action: Update the man page to state a reproducer is available, with a link to the Github Issue.
Again, this shows the lack of context by the LLM. If you are affected by the hardware errata when your driver is sending these malformed commands, it's your job to forward it to Huawei as a customer. It's not the responsibility for unpaid volunteers from a free software project who happens to write a driver for the same hardware to report a bug for you.
This driver is implemented and tested entirely by independent developers and users who collaborated through public forums on the Internet, thanks to Huawei's willingness to publish the public datasheet of this UPS model. So, unlike the Linux kernel where you can possibly find some insiders or people who know contacts, no one involved in this
huawei_ups2000driver was employed, sponsored, or contracted by Huawei, and no purchase/support contracts were involved. These UPS units were simply purchased ordered from online UPS resellers or second-hand markets. Thus, we do not have any Huawei contacts or negotiation power with Huawei to report a firmware problem. If you're powering your company's production system with Huawei's UPS, you're in a better position than us to report the problem.Conclusion
Please remove the tag "Connection stability issues". This is a hardware errata, not a connection stability issue, NUT drivers are not affected because these malformed commands are never generated.
However, it's arguably still a legitimate report:
I'll update the documentation with a link to the issue, and then we can close this bug.
docs/man/huawei-ups2000.txt: add serial port lockup documentation, close