juicedata/juicefs · critical

invalid unit

Error message

invalid unit

What it means

ParseBytesStr parses a human-readable byte size string (e.g. "10G", "512M") into a numeric value. It throws "invalid unit" when the string's trailing unit character is not one of the recognized SI/binary unit letters (k/K, m/M, g/G, t/T, p/P, e/E). After the error, the code calls logger.Fatalf, so the process terminates — the error is effectively fatal, not returnable.

Source

Thrown at pkg/utils/humanize.go:58

	val, err := strconv.ParseFloat(s, 64)
	if err == nil {
		var shift int
		switch unit {
		case 'B':
		case 'k', 'K':
			shift = 10
		case 'm', 'M':
			shift = 20
		case 'g', 'G':
			shift = 30
		case 't', 'T':
			shift = 40
		case 'p', 'P':
			shift = 50
		case 'e', 'E':
			shift = 60
		default:
			err = errors.New("invalid unit")
		}
		val *= float64(uint64(1) << shift)
	}
	if err != nil {
		logger.Fatalf("Invalid value \"%s\" for \"%s\": %s", str, key, err)
	}
	return uint64(val)
}

func ParseMbps(ctx *cli.Context, key string) int64 {
	str := ctx.String(key)
	if len(str) == 0 {
		return 0
	}

	return ParseMbpsStr(key, str)
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Use a supported single-letter unit: B (or none), k/K, m/M, g/G, t/T, p/P, e/E, e.g. "10G" instead of "10GiB".
  2. Check for trailing whitespace or stray characters in the value and trim them.
  3. Express fractional or precise sizes in the largest supported unit (e.g. 1536M instead of 1.5G).
  4. If the value comes from a config file, print it before parsing to confirm what string is actually being fed in.

Example fix

// before
ParseBytes("--block-size", "4MiB")
// after
ParseBytes("--block-size", "4M")
Defensive patterns

Strategy: validation

Validate before calling

var validUnits = "kmgtpeKMGTPE"
func validByteSize(s string) bool {
	s = strings.TrimSpace(s)
	if s == "" { return false }
	body, unit := s[:len(s)-1], s[len(s)-1]
	if !strings.ContainsAny(string(unit), validUnits) { return false }
	_, err := strconv.ParseFloat(body, 64)
	return err == nil
}
// call ParseBytes only if validByteSize(value)

Prevention

When it happens

Trigger: Calling utils.ParseBytes or ParseBytesStr with a string whose unit suffix is unrecognized: empty unit after a number where one is required, misspelled units ("10gi", "10kb" lowercase double-letter forms are not supported — only the first letter is examined), non-unit trailing characters ("10x", "10 "), or purely alphabetic junk passed as a size flag/config value.

Common situations: Users pass --block-size, --buffer-size, or cache-size flags with units the parser doesn't understand ("1.5GiB", "10 MB", "10kb") in mount or format commands; config files or environment-derived strings carry localized unit spellings; a YAML/JSON config field holds a plain number with an accidental suffix.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/c886bfd3a531f813. Report an issue: GitHub.