{"record":{"id":"5633d000c5a2782e","repo":"henrygd/beszel","slug":"battery-tag-not-returned","errorCode":null,"errorMessage":"battery tag not returned","messagePattern":"battery tag not returned","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"agent/battery/battery_windows.go","lineNumber":216,"sourceCode":"\tif err != nil {\n\t\treturn Battery{}, err\n\t}\n\tdefer windows.CloseHandle(handle)\n\n\tvar dwOut uint32\n\tvar dwWait uint32\n\tvar bqi batteryQueryInformation\n\terr = windows.DeviceIoControl(\n\t\thandle,\n\t\t2703424, // IOCTL_BATTERY_QUERY_TAG\n\t\t(*byte)(unsafe.Pointer(&dwWait)),\n\t\tuint32(unsafe.Sizeof(dwWait)),\n\t\t(*byte)(unsafe.Pointer(&bqi.BatteryTag)),\n\t\tuint32(unsafe.Sizeof(bqi.BatteryTag)),\n\t\t&dwOut, nil,\n\t)\n\tif err != nil || bqi.BatteryTag == 0 {\n\t\treturn Battery{}, errors.New(\"battery tag not returned\")\n\t}\n\n\tvar bi batteryInformation\n\tif err = windows.DeviceIoControl(\n\t\thandle,\n\t\t2703428, // IOCTL_BATTERY_QUERY_INFORMATION\n\t\t(*byte)(unsafe.Pointer(&bqi)),\n\t\tuint32(unsafe.Sizeof(bqi)),\n\t\t(*byte)(unsafe.Pointer(&bi)),\n\t\tuint32(unsafe.Sizeof(bi)),\n\t\t&dwOut, nil,\n\t); err != nil {\n\t\treturn Battery{}, err\n\t}\n\n\t// BatteryDeviceName is optional, so retain the deterministic fallback on error.\n\tname := \"\"\n\tnameQuery := bqi","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/agent/battery/battery_windows.go#L198-L234","documentation":"winBatteryGet on Windows first queries the battery query information (IOCTL_BATTERY_QUERY_TAG) to obtain a battery tag that identifies the battery device for subsequent calls. If the DeviceIoControl call fails or the returned tag is 0, the library cannot address the battery and throws this error. Tag 0 means no battery is present or the driver did not assign a tag.","triggerScenarios":"The device path opened from \\Device\\HarddiskVolumeShadowCopy*/battery or similar does not expose a valid battery interface, or the machine has no battery, or the battery driver failed to return a tag via IOCTL_BATTERY_QUERY_TAG (DeviceIoControl error or BatteryTag == 0).","commonSituations":"Running the agent on a desktop PC or VM without a battery; querying a battery device path after the battery was removed; running on a system where the battery driver (CmBatt/Battery) is not loaded; containers or services without access to the device.","solutions":["Verify the machine actually has a battery (acpi or powercfg /batteryreport).","Handle the error gracefully in GetBatteryStats and report 'no battery' instead of failing.","Check that the battery driver is loaded (Device Manager > Batteries) and re-scan.","Retry the device enumeration; tags are assigned at query time and can change when batteries are added/removed."],"exampleFix":"// before\nb, err := GetBatteryStats()\n// after\nb, err := GetBatteryStats()\nif err != nil && strings.Contains(err.Error(), \"battery tag not returned\") {\n\tlog.Info(\"no battery present, skipping battery reporting\")\n\treturn nil\n}","handlingStrategy":"fallback","validationCode":"// before calling GetBatteryStats on Windows\nif _, err := os.Stat(`\\\\.\\Battery0`); err != nil {\n\tlog.Info(\"no battery device present, skipping battery stats\")\n\treturn\n}","typeGuard":"func isNoBatteryErr(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"battery tag not returned\")\n}","tryCatchPattern":"b, err := GetBatteryStats()\nif err != nil {\n\tif isNoBatteryErr(err) {\n\t\treportBatteryUnavailable() // fall back to 'no battery' telemetry\n\t\treturn\n\t}\n\treturn err\n}","preventionTips":["Skip battery collection on machines known to have no battery (desktops, VMs).","Check Device Manager / WMI Win32_Battery presence before querying raw IOCTLs.","Re-enumerate battery devices periodically: battery tags can change.","Log the underlying DeviceIoControl error code for diagnostics."],"tags":["windows","hardware","battery","device-io"],"backgroundTag":"battery-tag-not-returned","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}