{"record":{"id":"eb387513bd8ece01","repo":"hashicorp/nomad","slug":"failed-to-parse-df-output-expected-at-least-4-c","errorCode":null,"errorMessage":"failed to parse `df` output; expected at least 4 columns","messagePattern":"failed to parse `df` output; expected at least 4 columns","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/fingerprint/storage_unix.go","lineNumber":48,"sourceCode":"\t} else {\n\t\tdfArgs = \"-k\"\n\t}\n\n\tmountOutput, err := exec.Command(\"df\", dfArgs, absPath).Output()\n\tif err != nil {\n\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":30,"sourceCodeEnd":61,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/fingerprint/storage_unix.go#L30-L61","documentation":"The data line of `df` output must contain at least 4 whitespace-separated columns (Filesystem, 1024-blocks, Used, Available, ...). If fields < 4, the volume and capacity cannot be extracted and this error is returned.","triggerScenarios":"strings.Fields(lines[1]) yields fewer than 4 columns because df produced a truncated or differently formatted data row (e.g. wrapped output, localized df, mount names containing newlines).","commonSituations":"Localized df headers/format changes; long mount paths on df without -P; third-party df replacements with different column layouts.","solutions":["Ensure GNU/BSD df with -P/-k flags is used (the code already passes -P on linux) so output is single-line.","Check `df -kP <path>` output manually for column count.","Fix locale environment (LC_ALL=C) if a localized df alters output.","Use DiskTotalMB config override to skip df parsing."],"exampleFix":"// before (env)\nLC_ALL=de_DE.UTF-8  # localized df output\n// after (service env)\nLC_ALL=C","handlingStrategy":"validation","validationCode":"out, _ := exec.Command(\"df\", \"-kP\", path).Output()\nlines := strings.Split(string(out), \"\\n\")\nif len(lines) < 2 || len(strings.Fields(lines[1])) < 4 {\n\treturn fmt.Errorf(\"df output columns unexpected; normalize df environment (LC_ALL=C, standard df)\")\n}","typeGuard":null,"tryCatchPattern":"if err := fp.Fingerprint(req); err != nil {\n\tif strings.Contains(err.Error(), \"expected at least 4 columns\") {\n\t\tlog.Printf(\"df columns unexpected: %v\", err)\n\t\treturn nil\n\t}\n\treturn err\n}","preventionTips":["Run clients with LC_ALL=C to keep df output stable.","Ensure -P (posix) output is available for long paths.","Avoid localized or third-party df implementations.","Provide DiskTotalMB override where df format cannot be controlled."],"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"}