Summary
get_system_stats() reads the system temperature with direct key access:
"temp_c": int(root["sys_tempc"]),
"temp_f": int(root["sys_tempf"]),
When a QNAP does not report a system temperature, these keys are absent from
the response and every call raises KeyError. That takes down the entire
library — disk, CPU, volume and network data included — even though the NAS
returns all of it correctly.
Two lines above, the same dict already guards an optional field:
root["cpu_model"] if "cpu_model" in root else None
The temperature fields did not get the same treatment.
This is not limited to old models
The unit I hit this on is a TS-253 Pro whose system temperature sensor is
faulty (confirmed by the owner). The API response corroborates it: the device
advertises a system temperature sensor and defines thresholds for it, but cannot
read it, and several neighbouring hardware readings come back as error
sentinels.
That is the important part: the field disappears when the sensor fails, not
only on models that never had one. Any QNAP can end up in this state. A unit
that works today will hard-fail the library the day its sensor dies — including
the TS-453E I mention below as the working case.
A failing hardware sensor should degrade one value. It should not make disk
temperatures, CPU load and volume usage unreachable.
Affected device
|
|
| Model |
QNAP TS-253 Pro (modelName: TS-X53) |
| Platform |
TS-NASX86 / X86_BAYTRAIL, Intel Celeron J1900 |
| Firmware |
QTS 5.2.10, build 3577 (2026-07-31) |
| Access |
HTTP, port 8080 |
| Known hardware issue |
System temperature sensor faulty |
Traceback
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/qnap/config_flow.py", line 64, in _async_validate_input
stats = await self.hass.async_add_executor_job(api.get_system_stats)
File "/usr/local/lib/python3.14/concurrent/futures/thread.py", line 86, in run
result = ctx.run(self.task)
File "/usr/local/lib/python3.14/concurrent/futures/thread.py", line 73, in run
return fn(*args, **kwargs)
File "/usr/local/lib/python3.14/site-packages/qnapstats/qnap_stats.py", line 232, in get_system_stats
"temp_c": int(root["sys_tempc"]),
~~~~^^^^^^^^^^^^^
KeyError: 'sys_tempc'
Evidence
Authentication and the request both succeed. I queried the exact endpoint the
library uses,
management/manaRequest.cgi?subfunc=sysinfo&hd=no&multicpu=1, and inspected
func > ownContent > root. It contains 87 fields, including everything the
library reads immediately before the failing line:
| Field |
Value |
|
server_name |
TUNANTE |
read OK |
serial_number |
present |
read OK |
cpu_model |
Intel(R) Celeron(R) CPU J1900 @ 2.00GHz |
read OK |
cpu_tempc / cpu_tempf |
48 / 118 |
read OK |
system_temp_count |
1 |
sensor is declared |
SysTempWarnT / SysTempErrT |
60 / 70 |
thresholds defined |
sys_tempc |
absent |
crash |
sys_tempf |
absent |
|
Corroborating the faulty-sensor diagnosis, the surrounding hardware readings are
error sentinels rather than values:
| Field |
Value |
Meaning |
sysfan1 |
4294967295 |
0xFFFFFFFF, i.e. unreadable |
sysfan1_stat |
-1 |
unknown |
temp_reg_cnt / fan_reg_cnt |
0 / 0 |
no readable registers |
Power1Temp / PowerFanStatus1 |
-1 / -1 |
unknown |
So the device declares the sensor, defines its thresholds, and then omits the
element entirely because it has no reading to give. The key is not empty — it is
not present at all.
For contrast, a TS-453E running the exact same firmware (QTS 5.2.10 build
3577), with a healthy sensor, does include both fields and works flawlessly.
The presence of the field tracks sensor health, not firmware version.
The data that is being thrown away
The disk data is fully available on the failing device, via
disk/qsmart.cgi?func=all_hd_data:
<Temperature><oC><![CDATA[45]]></oC><oF><![CDATA[113]]></oF></Temperature>
Disk temperature is arguably the single most useful thing this library exposes —
it is what tells you a drive is cooking. Losing it because an unrelated
enclosure sensor is broken is the worst possible failure mode: monitoring
disappears exactly on the machine that already has a hardware problem.
Expected behaviour
A missing or unreadable system temperature should yield None for that one
value, while disk temperatures, CPU stats, volumes and network counters continue
to be returned normally.
Proposed fix
Apply the same defensive pattern already used for cpu_model:
- "temp_c": int(root["sys_tempc"]),
- "temp_f": int(root["sys_tempf"]),
+ "temp_c": int(root["sys_tempc"]) if "sys_tempc" in root else None,
+ "temp_f": int(root["sys_tempf"]) if "sys_tempf" in root else None,
Consumers already have to handle optional values elsewhere in this dict, so
returning None is consistent with the existing contract.
Downstream impact
This breaks the official Home Assistant QNAP integration on affected devices:
the config flow fails with a generic "Unexpected error" and the integration
cannot be added at all. The message gives no hint of the real cause, so it reads
like a connectivity or credentials problem — I spent a while checking ports,
SSL and passwords before reading the traceback.
Home Assistant core issue #80065
reports the same KeyError: 'sys_tempc'.
Related history
The same class of problem has been reported repeatedly for other optional
fields on other models:
- #4 —
KeyError: 'cpu_model' on TS-639
- #8 —
KeyError: 'cpu_tempc' on TS-410
- #35 —
KeyError on TS-251+
Given that any of these fields can vanish when the corresponding sensor fails, a
broader hardening pass over the optional fields in get_system_stats() would
likely prevent the next report of this kind.
I am happy to open a pull request with the change above if that helps.
Summary
get_system_stats()reads the system temperature with direct key access:When a QNAP does not report a system temperature, these keys are absent from
the response and every call raises
KeyError. That takes down the entirelibrary — disk, CPU, volume and network data included — even though the NAS
returns all of it correctly.
Two lines above, the same dict already guards an optional field:
The temperature fields did not get the same treatment.
This is not limited to old models
The unit I hit this on is a TS-253 Pro whose system temperature sensor is
faulty (confirmed by the owner). The API response corroborates it: the device
advertises a system temperature sensor and defines thresholds for it, but cannot
read it, and several neighbouring hardware readings come back as error
sentinels.
That is the important part: the field disappears when the sensor fails, not
only on models that never had one. Any QNAP can end up in this state. A unit
that works today will hard-fail the library the day its sensor dies — including
the TS-453E I mention below as the working case.
A failing hardware sensor should degrade one value. It should not make disk
temperatures, CPU load and volume usage unreachable.
Affected device
modelName: TS-X53)TS-NASX86/X86_BAYTRAIL, Intel Celeron J1900Traceback
Evidence
Authentication and the request both succeed. I queried the exact endpoint the
library uses,
management/manaRequest.cgi?subfunc=sysinfo&hd=no&multicpu=1, and inspectedfunc > ownContent > root. It contains 87 fields, including everything thelibrary reads immediately before the failing line:
server_nameTUNANTEserial_numbercpu_modelIntel(R) Celeron(R) CPU J1900 @ 2.00GHzcpu_tempc/cpu_tempf48/118system_temp_count1SysTempWarnT/SysTempErrT60/70sys_tempcsys_tempfCorroborating the faulty-sensor diagnosis, the surrounding hardware readings are
error sentinels rather than values:
sysfan142949672950xFFFFFFFF, i.e. unreadablesysfan1_stat-1temp_reg_cnt/fan_reg_cnt0/0Power1Temp/PowerFanStatus1-1/-1So the device declares the sensor, defines its thresholds, and then omits the
element entirely because it has no reading to give. The key is not empty — it is
not present at all.
For contrast, a TS-453E running the exact same firmware (QTS 5.2.10 build
3577), with a healthy sensor, does include both fields and works flawlessly.
The presence of the field tracks sensor health, not firmware version.
The data that is being thrown away
The disk data is fully available on the failing device, via
disk/qsmart.cgi?func=all_hd_data:Disk temperature is arguably the single most useful thing this library exposes —
it is what tells you a drive is cooking. Losing it because an unrelated
enclosure sensor is broken is the worst possible failure mode: monitoring
disappears exactly on the machine that already has a hardware problem.
Expected behaviour
A missing or unreadable system temperature should yield
Nonefor that onevalue, while disk temperatures, CPU stats, volumes and network counters continue
to be returned normally.
Proposed fix
Apply the same defensive pattern already used for
cpu_model:Consumers already have to handle optional values elsewhere in this dict, so
returning
Noneis consistent with the existing contract.Downstream impact
This breaks the official Home Assistant QNAP integration on affected devices:
the config flow fails with a generic "Unexpected error" and the integration
cannot be added at all. The message gives no hint of the real cause, so it reads
like a connectivity or credentials problem — I spent a while checking ports,
SSL and passwords before reading the traceback.
Home Assistant core issue #80065
reports the same
KeyError: 'sys_tempc'.Related history
The same class of problem has been reported repeatedly for other optional
fields on other models:
KeyError: 'cpu_model'on TS-639KeyError: 'cpu_tempc'on TS-410KeyErroron TS-251+Given that any of these fields can vanish when the corresponding sensor fails, a
broader hardening pass over the optional fields in
get_system_stats()wouldlikely prevent the next report of this kind.
I am happy to open a pull request with the change above if that helps.