Skip to content

huawei-ups2000: UPS serial comm lockup triggered by 0x2B ReadDevID=0x01 + ObjectID=0x87 (reproducible "Serial port becomes unresponsive" case) #3735

Open

Description

@csc06

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.

  1. 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.
  2. Send: 01 2B 0E 01 87 <valid CRC-16> — command 0x2B, MEI 0x0E, ReadDevID 0x01, ObjectID 0x87.
  3. 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

  1. 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.
  2. 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

  1. csc06 commented on Oct 7, 2026

    @csc06
    Author

    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 own ident_req frame) works fine and returns the device list. This confirms:

    1. Object 0x87 itself is safe to request — the lockup is specific to the malformed basic-ReadDevID variant (ReadDevID=0x01).
    2. Device info for Huawei triage, decoded from the identification response:
      • Model family: UPS2000A (1 kVA, RS-232 via XR21V1410 USB-UART)
      • Firmware: V2R1C1SPC50
      • Protocol string: 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.

  2. jimklimov commented on Oct 7, 2026

    @jimklimov
    Member
  3. added
    HuaweiPR or issue regarding Huawei UPS or related products and protocols
    Connection stability issuesIssues about driver<->device and/or networked connections (upsd<->upsmon...) going AWOL over time
    on Oct 7, 2026
  4. biergaizi commented on Oct 19, 2026

    @biergaizi
    Contributor

    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.

    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: [...]

    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_ups2000 driver, 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.

    drivers/huawei-ups2000.c never sends such a frame (its ident_req correctly uses ReadDevID=0x03)

    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 0x03 was 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).

    Some malformed commands are known to lock up the serial port (including USB, which is a USB-to-serial device). Upon receiving them, UPS2000 stops all serial communications. The result is a completely unresponsive UPS, regardless of what you do -- restarting NUT, rebooting the computer -- can not restore connectivity, as if someone has unplugged the RS-232 cable. To recover, simply power cycle the UPS: Turn off the UPS output via the front panel, then unplug the UPS from line power. Wait for the LCD front screen to go black. Finally reconnect line power and restart your UPS. That being said, a serial port lockup is unlikely to happen. To our best knowledge, this driver never sends malformed commands to the UPS (it was only a problem during early development). Furthermore, due to a CRC checksum, they're unlikely to be accidentally generated. Still, we recommend to power cycle your UPS after making a cabling change, especially after changing from RS-485/USB to RS-232, just to ensure the UPS selects the correct communication interface. Also, if you have discovered a reproducible serial port lockup problem, it can be a previously unknown bug, so please make sure to file a bug report.

    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.

    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.

    The man page is end-user documentation, not developer documentation. The man page is supposed to be a documentation of the huawei_ups2000 device 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.

    Suggested actions: 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).

    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_ups2000 driver 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:

    1. In the bug tracker, there's a category defined as "documentation protocol": Submitted vendor-provided or user-discovered protocol information, or similar data (measurements...). This report clearly fits within this category.
    2. It's arguably a documentation bug, because the documentation only says "also, if you have discovered a reproducible serial port lockup problem, it can be a previously unknown bug, so please make sure to file a bug report." The implied context is that the problem is caused by the driver, because this sentence appeared in the driver's man page, which I believe most humans would understand the context. But a LLM took a literal read of the sentence, so a bug report was submitted as described.
    3. This report is itself a useful contribution, in the sense of documenting the errata, so although it's not the responsibility of the man page to describe the hardware errata, but linking to this errata report on the bug tracker from the man page with a URL would be perfectly reasonable.

    I'll update the documentation with a link to the issue, and then we can close this bug.

  5. added
    documentation-protocolSubmitted vendor-provided or user-discovered protocol information, or similar data (measurements...)
    AIFor good or bad, machine tools are upon us. Humans are still the responsible ones.
    and removed
    Connection stability issuesIssues about driver<->device and/or networked connections (upsd<->upsmon...) going AWOL over time
    on Oct 19, 2026
  6. added a commit that references this issue on Oct 19, 2026
    ede5ac5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    AIFor good or bad, machine tools are upon us. Humans are still the responsible ones.HuaweiPR or issue regarding Huawei UPS or related products and protocolsdocumentation-protocolSubmitted vendor-provided or user-discovered protocol information, or similar data (measurements...)modbus

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions