{"record":{"id":"3543749c897690bf","repo":"henrygd/beszel","slug":"unexpected-arcstats-size-format-s","errorCode":null,"errorMessage":"unexpected arcstats size format: %s","messagePattern":"unexpected arcstats size format: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"agent/zfs/zfs_linux.go","lineNumber":27,"sourceCode":"\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc ARCSize() (uint64, error) {\n\tfile, err := os.Open(\"/proc/spl/kstat/zfs/arcstats\")\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\tif strings.HasPrefix(line, \"size\") {\n\t\t\tfields := strings.Fields(line)\n\t\t\tif len(fields) < 3 {\n\t\t\t\treturn 0, fmt.Errorf(\"unexpected arcstats size format: %s\", line)\n\t\t\t}\n\t\t\treturn strconv.ParseUint(fields[2], 10, 64)\n\t\t}\n\t}\n\n\treturn 0, fmt.Errorf(\"size field not found in arcstats\")\n}\n","sourceCodeStart":9,"sourceCodeEnd":35,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/agent/zfs/zfs_linux.go#L9-L35","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Ensure the ZFS kernel module is properly loaded and matches userspace tools; reload it if kstat output is malformed.","Confirm the code opens /proc/spl/kstat/zfs/arcstats and not a stale fixture or wrong symlink.","Re-read the file; a truncated read can be transient and may succeed on retry."],"exampleFix":"// before\nreturn 0, fmt.Errorf(\"unexpected arcstats size format: %s\", line)\n// after\nreturn 0, fmt.Errorf(\"unexpected arcstats size format (%d fields): %q\", len(fields), line)\n// or use a tolerant regex: re := regexp.MustCompile(`^size\\s+\\d+\\s+(\\d+)$`)","handlingStrategy":"validation","validationCode":"// sanity-check the arcstats file before parsing\ndata, err := os.ReadFile(\"/proc/spl/kstat/zfs/arcstats\")\nif err != nil || !strings.Contains(string(data), \"size\") {\n\t// treat ARC size as unavailable\n}","typeGuard":"func arcLineValid(fields []string) bool {\n\tif len(fields) < 3 { return false }\n\t_, err := strconv.ParseUint(fields[2], 10, 64)\n\treturn err == nil\n}","tryCatchPattern":"size, err := zfs.ARCSize()\nif err != nil {\n\tlog.Printf(\"arcstats unavailable: %v\", err) // degrade gracefully\n\tsize = 0\n}","preventionTips":["Parse kstat lines as name/type/value triples and validate types.","Check the ZFS module is loaded before reading /proc/spl.","Mount /proc/spl into containers if metrics are needed there.","Log the offending raw line for diagnosis."],"tags":["go","zfs","procfs","parsing"],"backgroundTag":"unexpected-file-format","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}