cloudflare/cloudflared · error

expected disk volume to have

Error message

expected disk volume to have %d fields got %d: %w

What it means

ParseDiskVolumeInformationOutput validates that each line of `df`-style disk volume output contains at least `diskFieldsMinimum` whitespace-separated fields. When a line is too sparse it returns ErrInsuficientFields wrapped in this message, since fields like device name and mount point cannot be extracted reliably from a malformed line.

Solutions

  1. Strip the df header line before parsing (skip the first line or filter lines starting with 'Filesystem').
  2. Call df with portable flags (e.g. `df -P -k`) so every data line has the standard 6 columns.
  3. Check the df output on the failing host for line wrapping — use longer device-name output or `-P` to prevent wraps.
  4. Set LC_ALL=C when invoking df to avoid locale-dependent column variations.

Example fix

// before
out, _ := exec.Command("df").Output()
info, err := diagnostic.ParseDiskVolumeInformationOutput(string(out))
// after
out, _ := exec.Command("df", "-P", "-k").Output()
lines := strings.Split(string(out), "\n")
if len(lines) > 0 {
	lines = lines[1:] // drop header
}
info, err := diagnostic.ParseDiskVolumeInformationOutput(strings.Join(lines, "\n"))
Defensive patterns

Strategy: validation

Validate before calling

func validateDiskOutput(output string) error {
	for _, line := range strings.Split(output, "\n") {
		line = strings.TrimSpace(line)
		if line == "" || strings.HasPrefix(line, "Filesystem") {
			continue
		}
		if len(strings.Fields(line)) < 6 {
			return fmt.Errorf("disk line too short: %q", line)
		}
	}
	return nil
}

Try / catch

info, err := diagnostic.ParseDiskVolumeInformationOutput(dfOutput)
var target error = diagnostic.ErrInsuficientFields
if errors.Is(err, target) {
	log.Warn().Msg("skipping malformed disk volume line")
} else if err != nil {
	return fmt.Errorf("disk parse failed: %w", err)
}

Prevention

When it happens

Trigger: Calling ParseDiskVolumeInformationOutput (directly or via collectDiskVolumeInformationUnix/collectDiskVolumeInformation during Collect) with df output whose header line or a truncated line has fewer fields than diskFieldsMinimum — e.g. parsing df output that still includes the 'Filesystem ... Mount on' header, or a locale producing extra/short lines.

Common situations: Forgetting `df -P` style normalization so wrapped device names split across lines, localized df headers/columns on non-English systems, empty or partial output when the disk is unavailable, or feeding the function raw output that includes blank or banner lines.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/0ab5e4d70fe35561. Report an issue: GitHub.

Appendix: source

Thrown at diagnostic/system_collector_utils.go:87

		sizeCurrentField  = 2
	)

	disksRaw := strings.Split(output, "\n")
	disks := make([]*DiskVolumeInformation, 0)

	if skipLines > len(disksRaw) || skipLines < 0 {
		skipLines = 0
	}

	for _, disk := range disksRaw[skipLines:] {
		if disk == "" {
			// skip empty line
			continue
		}

		fields := strings.Fields(disk)
		if len(fields) < diskFieldsMinimum {
			return nil, fmt.Errorf("expected disk volume to have %d fields got %d: %w",
				diskFieldsMinimum, len(fields), ErrInsuficientFields,
			)
		}

		name := fields[nameField]

		sizeMaximum, err := strconv.ParseUint(fields[sizeMaximumField], 10, 64)
		if err != nil {
			continue
		}

		sizeCurrent, err := strconv.ParseUint(fields[sizeCurrentField], 10, 64)
		if err != nil {
			continue
		}

		diskInfo := NewDiskVolumeInformation(
			name, uint64(float64(sizeMaximum)*scale), uint64(float64(sizeCurrent)*scale),

View on GitHub (pinned to 2253eeeb25)