docker/cli · error
value is too precise
Error message
value is too precise
What it means
Returned by ParseCPUs (opts/opts.go:366) when a CPU ratio string, after being parsed as a big.Rat and multiplied by 1e9 (to convert to nano-CPUs), does not produce a whole integer. This means the requested precision exceeds nanosecond granularity — the value has more significant decimal places than 9, or is a fraction that doesn't divide evenly into whole nanos.
Solutions
- Round the CPU value to at most 3 decimal places (1ms precision): '--cpus 0.5', '--cpus 1.25', '--cpus 0.001'.
- Avoid fractional denominators that don't divide 1e9 evenly; use decimal notation instead of rational fractions.
- If computing CPU from a formula, round the result before passing to --cpus.
Example fix
// before: too many decimal places // docker run --cpus=0.1234567891 nginx // after: round to 3 decimal places // docker run --cpus=0.123 nginx
Defensive patterns
Strategy: validation
Validate before calling
func validateCPUPrecision(value string) error {
cpu, ok := new(big.Rat).SetString(value)
if !ok {
return fmt.Errorf("failed to parse %s as a rational number", value)
}
nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
if !nano.IsInt() {
return fmt.Errorf("CPU value %s is too precise; round to at most 3 decimal places (e.g., 0.5, 1.25)", value)
}
return nil
} Try / catch
if _, err := opts.ParseCPUs(value); err != nil {
if err.Error() == "value is too precise" {
return fmt.Errorf("CPU value %q exceeds nano-precision; round to <= 3 decimal places", value)
}
return err
} Prevention
- Round CPU values to at most 3 decimal places (e.g., 0.5, 1.25, 0.001).
- Avoid rational fractions (like 1/3) that don't divide evenly into whole nanoseconds.
- Validate computed CPU values with ParseCPUs before formatting into --cpus flags.
When it happens
Trigger: ParseCPUs (used by the --cpus flag via NanoCPUs.Set) receives a value with more than 9 decimal places of CPU precision, or a rational fraction whose product with 1e9 is non-integer. For example: '--cpus 0.1234567891' (10 decimal places) or '--cpus 1/7'. The big.Rat multiplication by 1e9 yields a non-integer result, so nano.IsInt() returns false.
Common situations: Over-precise CPU specification, programmatic generation of CPU values with excessive decimal places, or passing a rational fraction like '1/3' that doesn't map to whole nanoseconds.
Related errors
- duration cannot be negative
- value is empty
- invalid field key
- network name/id is not specified
- invalid key value pair format in driver options
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/eb3824f4e7cca48a.
Report an issue: GitHub.
Appendix: source
Thrown at opts/opts.go:366
// Type returns the type
func (*NanoCPUs) Type() string {
return "decimal"
}
// Value returns the value in int64
func (c *NanoCPUs) Value() int64 {
return int64(*c)
}
// ParseCPUs takes a string ratio and returns an integer value of nano cpus
func ParseCPUs(value string) (int64, error) {
cpu, ok := new(big.Rat).SetString(value)
if !ok {
return 0, fmt.Errorf("failed to parse %v as a rational number", value)
}
nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
if !nano.IsInt() {
return 0, errors.New("value is too precise")
}
return nano.Num().Int64(), nil
}
// ParseLink parses and validates the specified string as a link format (name:alias)
func ParseLink(val string) (string, string, error) {
if val == "" {
return "", "", errors.New("empty string specified for links")
}
// We expect two parts, but restrict to three to allow detecting invalid formats.
arr := strings.SplitN(val, ":", 3)
// TODO(thaJeztah): clean up this logic!!
if len(arr) > 2 {
return "", "", errors.New("bad format for links: " + val)
}
// TODO(thaJeztah): this should trim the "/" prefix as well??
if len(arr) == 1 {View on GitHub (pinned to 4f84911bfe)