docker/cli · error
bad format
Error message
bad format: %s
What it means
Returned by ValidateThrottleBpsDevice (the validator behind --device-read-bps / --device-write-bps) when the input has no ':' separator or the device-path part (left of ':') is empty. The expected format is '<device-path>:<number>[<unit>]'.
Solutions
- Provide the full '<device-path>:<rate>' pair, e.g. '--device-read-bps=/dev/sda:1mb'.
- Put the device path on the left of the colon and the rate on the right.
- Ensure the device path is non-empty (starts with /dev/ — see the next check).
Example fix
# before docker run --device-read-bps=1mb ubuntu # after docker run --device-read-bps=/dev/sda:1mb ubuntu
Defensive patterns
Strategy: validation
Validate before calling
// Reject values missing the '<device>:<rate>' shape before ValidateThrottleBpsDevice.
import "strings"
func hasBpsShape(s string) bool {
k, v, ok := strings.Cut(s, ":")
return ok && k != "" && v != ""
}
// if !hasBpsShape(val) { return fmt.Errorf("expected <device-path>:<rate>, got %q", val) } Try / catch
if _, err := opts.ValidateThrottleBpsDevice(val); err != nil {
// err: bad format: <val>
return err
} Prevention
- Always include both the device path and the rate, separated by a colon.
- Put the device on the left, rate on the right.
- Pre-flight with a 'strings.Cut(s, ":")' shape check in your wrapper.
When it happens
Trigger: 'docker run --device-read-bps=1mb' (no colon, no device), '--device-read-bps=:1mb' (empty device key), or any value where strings.Cut(val, ":") yields ok=false.
Common situations: Forgetting the device path and passing only a rate, or swapping the order ('1mb:/dev/sda'). Happens when users assume the flag takes just a rate and apply it globally.
Related errors
- bad format for device path
- invalid rate for device
- invalid rate for device
- bad format
- bad format for device path
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/bde475062c009428.
Report an issue: GitHub.
Appendix: source
Thrown at opts/throttledevice.go:19
package opts
import (
"fmt"
"strconv"
"strings"
"github.com/docker/go-units"
"github.com/moby/moby/api/types/blkiodev"
)
// ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error.
type ValidatorThrottleFctType func(val string) (*blkiodev.ThrottleDevice, error)
// ValidateThrottleBpsDevice validates that the specified string has a valid device-rate format.
func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
k, v, ok := strings.Cut(val, ":")
if !ok || k == "" {
return nil, fmt.Errorf("bad format: %s", val)
}
// TODO(thaJeztah): should we really validate this on the client?
if !strings.HasPrefix(k, "/dev/") {
return nil, fmt.Errorf("bad format for device path: %s", val)
}
rate, err := units.RAMInBytes(v)
if err != nil {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
}
if rate < 0 {
return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
}
return &blkiodev.ThrottleDevice{
Path: k,
Rate: uint64(rate),
}, nil
}View on GitHub (pinned to 4f84911bfe)