henrygd/beszel · warning

unexpected arcstats size format: %s

Error message

unexpected arcstats size format: %s

What it means

ARCSize parses /proc/spl/kstat/zfs/arcstats on Linux to read the ZFS ARC cache size. Each kstat line is `name type value`; a line starting with `size` that has fewer than 3 whitespace-separated fields cannot be parsed, so the function returns this error instead of guessing a value.

Source

Thrown at agent/zfs/zfs_linux.go:27

	"os"
	"strconv"
	"strings"
)

func ARCSize() (uint64, error) {
	file, err := os.Open("/proc/spl/kstat/zfs/arcstats")
	if err != nil {
		return 0, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := scanner.Text()
		if strings.HasPrefix(line, "size") {
			fields := strings.Fields(line)
			if len(fields) < 3 {
				return 0, fmt.Errorf("unexpected arcstats size format: %s", line)
			}
			return strconv.ParseUint(fields[2], 10, 64)
		}
	}

	return 0, fmt.Errorf("size field not found in arcstats")
}

View on GitHub (pinned to b38fb7dafa)

Solutions

  1. Verify the real file: `grep size /proc/spl/kstat/zfs/arcstats` should show `size 4 <number>`; a nonstandard line means the kernel module output changed.
  2. Ensure the ZFS kernel module is properly loaded and matches userspace tools; reload it if kstat output is malformed.
  3. Confirm the code opens /proc/spl/kstat/zfs/arcstats and not a stale fixture or wrong symlink.
  4. Re-read the file; a truncated read can be transient and may succeed on retry.

Example fix

// before
return 0, fmt.Errorf("unexpected arcstats size format: %s", line)
// after
return 0, fmt.Errorf("unexpected arcstats size format (%d fields): %q", len(fields), line)
// or use a tolerant regex: re := regexp.MustCompile(`^size\s+\d+\s+(\d+)$`)
Defensive patterns

Strategy: validation

Validate before calling

// sanity-check the arcstats file before parsing
data, err := os.ReadFile("/proc/spl/kstat/zfs/arcstats")
if err != nil || !strings.Contains(string(data), "size") {
	// treat ARC size as unavailable
}

Type guard

func arcLineValid(fields []string) bool {
	if len(fields) < 3 { return false }
	_, err := strconv.ParseUint(fields[2], 10, 64)
	return err == nil
}

Try / catch

size, err := zfs.ARCSize()
if err != nil {
	log.Printf("arcstats unavailable: %v", err) // degrade gracefully
	size = 0
}

Prevention

When it happens

Trigger: The arcstats file contains a `size` line with fewer than 3 fields — a malformed/truncated /proc read, a modified kernel module, or reading a simulated/kstat file that doesn't follow the standard three-column layout.

Common situations: ZFS kernel module changed output format; container or chroot exposing a partial /proc/spl tree; mocked arcstats fixtures with the wrong format; truncated procfs reads under heavy load.

Related errors


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