henrygd/beszel · error

%s - %w - see https://github.com/henrygd/beszel/issues/144

Error message

%s - %w - see https://github.com/henrygd/beszel/issues/144

What it means

updateContainerStats computes memory usage from the Docker/Podman stats response via calculateMemoryUsage. When that calculation fails (usually because the stats payload lacks expected memory fields), the error is wrapped with the container name and a link to beszel issue #144. This is a known quirk where Podman (or cgroup-v2-only setups) reports memory stats differently from Docker.

Source

Thrown at agent/docker.go:566

	// Podman reports system_cpu_usage from cgroup cpu.stat (not /proc/stat), so it reflects
	// only cgroup-tracked activity rather than total host capacity. Use a time-based method
	// instead so the result is comparable to host CPU utilization. See:
	// https://github.com/henrygd/beszel/issues/2049
	var cpuPct float64
	if dm.isWindows {
		prevRead := dm.lastCpuReadTime[cacheTimeMs][ctr.IdShort]
		cpuPct = res.CalculateCpuPercentWindows(prevCpuContainer, prevRead)
	} else if dm.usingPodman && res.CPUStats.OnlineCPUs > 0 {
		prevRead := dm.lastCpuReadTime[cacheTimeMs][ctr.IdShort]
		cpuPct = res.CalculateCpuPercentPodman(prevCpuContainer, prevRead)
	} else {
		cpuPct = res.CalculateCpuPercentLinux(prevCpuContainer, prevCpuSystem)
	}

	// Calculate memory usage
	usedMemory, err := calculateMemoryUsage(res, dm.isWindows)
	if err != nil {
		return fmt.Errorf("%s - %w - see https://github.com/henrygd/beszel/issues/144", name, err)
	}

	// Store current CPU stats for next calculation
	currentCpuContainer := res.CPUStats.CPUUsage.TotalUsage
	currentCpuSystem := res.CPUStats.SystemUsage
	dm.setCpuCurrentValues(cacheTimeMs, ctr.IdShort, currentCpuContainer, currentCpuSystem)

	// Validate CPU percentage
	if err := validateCpuPercentage(cpuPct, name); err != nil {
		return err
	}

	// Calculate network stats using DeltaTracker
	sent_delta, recv_delta := dm.calculateNetworkStats(ctr, res, name, cacheTimeMs)

	// Store per-cache-time network read time for next rate calculation
	if dm.lastNetworkReadTime[cacheTimeMs] == nil {
		dm.lastNetworkReadTime[cacheTimeMs] = make(map[string]time.Time)

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Check beszel issue #144 for the exact Podman/cgroup version affected and workarounds
  2. Update Podman/Docker to a version that reports memory_stats.usage correctly
  3. Verify cgroup controller availability (memory controller enabled for the agent's cgroup)
  4. Guard the stats loop so one container's memory-parse failure does not abort other containers

Example fix

// before: whole update fails on memory calc
usedMemory, err := calculateMemoryUsage(res, dm.isWindows)
if err != nil {
    return fmt.Errorf("%s - %w - see https://github.com/henrygd/beszel/issues/144", name, err)
}
// after: degrade gracefully
usedMemory, err := calculateMemoryUsage(res, dm.isWindows)
if err != nil {
    log.Debug("memory stats unavailable", "container", name, "err", err)
    usedMemory = 0
}
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check the stats payload before computing memory
if len(res.MemoryStats.Stats) == 0 || res.MemoryStats.Usage == 0 {
    // skip memory calculation for this sample
}

Try / catch

if err := updateContainerStats(ctr); err != nil {
    if strings.Contains(err.Error(), "issues/144") {
        log.Debug("podman memory stats unsupported", "container", ctr.Name)
    } else {
        log.Error("stats update failed", "err", err)
    }
}

Prevention

When it happens

Trigger: calculateMemoryUsage returns an error while processing a stats response — e.g. memory_stats missing or zeroed, cache/usage fields absent, which happens with certain Podman versions and rootless/cgroup-v2 configurations.

Common situations: Running the agent against Podman sockets where stats JSON omits or renames memory fields; kernels with cgroup v2 where some memory stats are not exposed; containers that just exited mid-stats-read returning partial data.

Related errors


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