{"record":{"id":"146a34cdff7341e6","repo":"hashicorp/nomad","slug":"failed-to-parse-storage-bytestotal-size-in-kilobyt","errorCode":null,"errorMessage":"failed to parse storage.bytestotal size in kilobytes","messagePattern":"failed to parse storage\\.bytestotal size in kilobytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/fingerprint/storage_unix.go","lineNumber":54,"sourceCode":"\t\treturn \"\", 0, fmt.Errorf(\"failed to determine mount point for %s\", absPath)\n\t}\n\t// Output looks something like:\n\t//\tFilesystem 1024-blocks      Used Available Capacity   iused    ifree %iused  Mounted on\n\t//\t/dev/disk1   487385240 423722532  63406708    87% 105994631 15851677   87%   /\n\t//\t[0] volume [1] capacity [2] SKIP  [3] free\n\tlines := strings.Split(string(mountOutput), \"\\n\")\n\tif len(lines) < 2 {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to parse `df` output; expected at least 2 lines\")\n\t}\n\tfields := strings.Fields(lines[1])\n\tif len(fields) < 4 {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to parse `df` output; expected at least 4 columns\")\n\t}\n\tvolume = fields[0]\n\n\ttotal, err = strconv.ParseUint(fields[1], 10, 64)\n\tif err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to parse storage.bytestotal size in kilobytes\")\n\t}\n\t// convert to bytes\n\ttotal *= 1024\n\n\treturn volume, total, nil\n}\n","sourceCodeStart":36,"sourceCodeEnd":61,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/fingerprint/storage_unix.go#L36-L61","documentation":"After extracting columns, diskInfo parses field[1] (size in 1K blocks) with strconv.ParseUint. If the column is not a plain unsigned decimal, parsing fails and this error is returned before converting to bytes.","triggerScenarios":"df data row's 1024-blocks column contains non-numeric text — corrupt/truncated df output, a df replacement printing units (e.g. '1.5T') or placeholder values ('-').","commonSituations":"Wrapper scripts around df; filesystems reporting '-' for size; output mangled by locale thousands separators.","solutions":["Inspect raw `df -k <path>` output and confirm the second column is a plain integer.","Remove any df wrapper script or ensure it emits standard output.","Set LC_ALL=C to avoid locale separators in numbers.","Configure DiskTotalMB to bypass df-based detection entirely."],"exampleFix":"// before\ndf() { /bin/df -h \"$@\"; }  # -h prints '1.5T' style sizes\n// after\n# remove wrapper; code calls `df -k` expecting raw kilobyte integers","handlingStrategy":"validation","validationCode":"out, _ := exec.Command(\"df\", \"-kP\", path).Output()\nlines := strings.Split(string(out), \"\\n\")\nif len(lines) < 2 { return fmt.Errorf(\"no df data row\") }\nfields := strings.Fields(lines[1])\nif len(fields) < 4 { return fmt.Errorf(\"df columns missing\") }\nif _, err := strconv.ParseUint(fields[1], 10, 64); err != nil {\n\treturn fmt.Errorf(\"df size column %q not an integer; remove df wrappers or set DiskTotalMB\", fields[1])\n}","typeGuard":null,"tryCatchPattern":"if err := fp.Fingerprint(req); err != nil {\n\tif strings.Contains(err.Error(), \"failed to parse storage.bytestotal\") {\n\t\tlog.Printf(\"df size column unparseable: %v\", err)\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Remove df wrapper scripts that emit human-readable sizes (-h).","Set LC_ALL=C to prevent locale formatting of numbers.","Verify df's 1024-blocks column is a plain integer on target hosts.","Use DiskTotalMB config override to bypass parsing."],"tags":["filesystem","df","parsing","fingerprinting"],"backgroundTag":"df-output-parse-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}