hashicorp/nomad · error

failed to parse `df` output; expected at least 2 lines

Error message

failed to parse `df` output; expected at least 2 lines

What it means

In StorageFingerprint.diskInfo, the output of running `df -kP <path>` has fewer than 2 lines, meaning the df invocation returned output in an unexpected format (or the mount point lookup failed earlier), so volume name and free bytes cannot be extracted for the storage fingerprint.

Source

Thrown at client/fingerprint/storage_unix.go:44

	var dfArgs string
	if runtime.GOOS == "linux" {
		// df on linux needs the -P option to prevent linebreaks on long filesystem paths
		dfArgs = "-kP"
	} else {
		dfArgs = "-k"
	}

	mountOutput, err := exec.Command("df", dfArgs, absPath).Output()
	if err != nil {
		return "", 0, fmt.Errorf("failed to determine mount point for %s", absPath)
	}
	// Output looks something like:
	//	Filesystem 1024-blocks      Used Available Capacity   iused    ifree %iused  Mounted on
	//	/dev/disk1   487385240 423722532  63406708    87% 105994631 15851677   87%   /
	//	[0] volume [1] capacity [2] SKIP  [3] free
	lines := strings.Split(string(mountOutput), "\n")
	if len(lines) < 2 {
		return "", 0, fmt.Errorf("failed to parse `df` output; expected at least 2 lines")
	}
	fields := strings.Fields(lines[1])
	if len(fields) < 4 {
		return "", 0, fmt.Errorf("failed to parse `df` output; expected at least 4 columns")
	}
	volume = fields[0]

	total, err = strconv.ParseUint(fields[1], 10, 64)
	if err != nil {
		return "", 0, fmt.Errorf("failed to parse storage.bytestotal size in kilobytes")
	}
	// convert to bytes
	total *= 1024

	return volume, total, nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify `df -k <path>` manually prints a header plus one data row.
  2. Use a standard df (GNU coreutils / BSD) rather than a minimal replacement.
  3. Pin the platform image to one with known-good coreutils.
  4. Provide DiskTotalMB override to bypass df parsing.

Example fix

// before
PATH="$CUSTOM_BIN:$PATH" df ...  # nonstandard df
// after
apt-get install -y coreutils  # standard df on PATH
Defensive patterns

Strategy: validation

Validate before calling

out, err := exec.Command("df", "-k", path).Output()
if err != nil || len(strings.Split(string(out), "\n")) < 2 {
	return fmt.Errorf("df output not parseable for %s; check df implementation", path)
}

Try / catch

if err := fp.Fingerprint(req); err != nil {
	if strings.Contains(err.Error(), "expected at least 2 lines") {
		log.Printf("df output shape unexpected: %v", err)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: df output for absPath contains fewer than 2 newline-separated lines — e.g. df emitted only an error/usage line to stdout or no data row for the path.

Common situations: Non-standard df implementations (BusyBox variants, exotic platforms) with unexpected output; df writing diagnostics instead of a table; locale/behavior differences after OS upgrades.

Understand the failure class

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/79c360cc1b813bf0. Report an issue: GitHub.