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
- 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".
- Check for trailing whitespace or stray characters in the value and trim them.
- Express fractional or precise sizes in the largest supported unit (e.g. 1536M instead of 1.5G).
- 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
- Standardize on single-letter units (K, M, G, T) in all configs and docs
- Trim whitespace from size strings before parsing
- Add a config-level schema check that validates size fields against the accepted unit set
- Remember only the last character is the unit — never write GiB/MiB/kbps style suffixes
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
- cannot disable dir stats when there are still %d dir quotas:
- parse quota key %q: %s
- url parse %s: %s
- load setting: %v
- New quota is too small (used / quota): %d / %d bytes, %d / %
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/c886bfd3a531f813.
Report an issue: GitHub.