henrygd/beszel · warning

battery capacity unknown

Error message

battery capacity unknown

What it means

After querying BATTERY_STATUS (capacities are in mWh), winBatteryGet validates the values: a capacity of 0xffffffff is the Windows 'unknown' sentinel, and FullChargedCapacity of 0 means division by zero would occur. If either is invalid, the library throws this error because a meaningful percent cannot be computed.

Source

Thrown at agent/battery/battery_windows.go:261

		name = windows.UTF16ToString(nameBuffer)
	}

	bws := batteryWaitStatus{BatteryTag: bqi.BatteryTag}
	var bs batteryStatus
	if err = windows.DeviceIoControl(
		handle,
		2703436, // IOCTL_BATTERY_QUERY_STATUS
		(*byte)(unsafe.Pointer(&bws)),
		uint32(unsafe.Sizeof(bws)),
		(*byte)(unsafe.Pointer(&bs)),
		uint32(unsafe.Sizeof(bs)),
		&dwOut, nil,
	); err != nil {
		return Battery{}, err
	}

	if bs.Capacity == 0xffffffff || bi.FullChargedCapacity == 0 || bi.FullChargedCapacity == 0xffffffff {
		return Battery{}, errors.New("battery capacity unknown")
	}
	percent := min(float64(bs.Capacity)/float64(bi.FullChargedCapacity)*100, 100)
	return Battery{Name: name, Percent: uint8(percent), State: readWinBatteryState(bs.PowerState),
		FullChargeCapacity: uint64(bi.FullChargedCapacity), HasFullChargeCapacity: true, System: true}, nil
}

// HasReadableBattery checks if the system has a battery and returns true if it does.
func HasReadableBattery() bool {
	batteries, _ := GetBatteryStats()
	return len(batteries) > 0
}

// GetBatteryStats returns every readable battery reported by Windows.
func GetBatteryStats() ([]Battery, error) {
	batteries := make([]Battery, 0, 2)
	for i := 0; ; i++ {
		battery, bErr := winBatteryGet(i)
		if errors.Is(bErr, errNotFound) {

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Retry the query after a short delay (e.g. 1-2s), as the driver may report unknown values transiently.
  2. Treat the error as 'capacity unknown' and report battery state without a percent value.
  3. Check battery info via powercfg /batteryreport to see if the firmware exposes FullChargedCapacity at all.
  4. Update the battery/ACPI driver or BIOS if the value is permanently unknown.

Example fix

// before
b, err := GetBatteryStats()
pct := b.Percent
// after
b, err := GetBatteryStats()
if err != nil && strings.Contains(err.Error(), "battery capacity unknown") {
	log.Warn("battery capacity unavailable; skipping percent")
	return nil
}
pct := b.Percent
Defensive patterns

Strategy: retry

Validate before calling

// sanity-check reported values before computing percent
capacityOK := bs.Capacity != 0xffffffff &&
	bi.FullChargedCapacity != 0 && bi.FullChargedCapacity != 0xffffffff

Type guard

func isCapacityUnknownErr(err error) bool {
	return err != nil && strings.Contains(err.Error(), "battery capacity unknown")
}

Try / catch

b, err := GetBatteryStats()
if isCapacityUnknownErr(err) {
	time.Sleep(2 * time.Second)
	b, err = GetBatteryStats() // transient right after resume
}
if err != nil {
	reportBatteryStateOnly() // still report charge state without percent
	return
}

Prevention

When it happens

Trigger: BATTERY_STATUS returns Capacity == 0xffffffff (unknown), or batteryInformation.FullChargedCapacity is 0 or 0xffffffff — i.e. the driver reports capacities as unknown. This often happens immediately after wake/resume or during driver initialization.

Common situations: Smart batteries that don't expose FullChargedCapacity (non-Smart Battery spec); transient states right after suspend/resume; VMs or exotic hardware with partially implemented ACPI battery methods; reading capacity before the driver refreshes it.

Related errors


AI-assisted analysis of henrygd/beszel@b38fb7dafa (2026-08-31). Data as JSON: /api/errors/195aaa9704916250. Report an issue: GitHub.