hashicorp/nomad · error
one of LimitBytes or RequiredBytes must be set if CapacityRa
Error message
one of LimitBytes or RequiredBytes must be set if CapacityRange is set
What it means
ControllerCreateVolumeRequest.Validate() rejects a CapacityRange where both LimitBytes and RequiredBytes are zero. If you declare a capacity range at all, it must contain at least one meaningful bound; an all-zero range conveys no constraint and is treated as a caller bug.
Source
Thrown at plugins/csi/plugin.go:501
Parameters: r.Parameters,
Secrets: r.Secrets,
VolumeContentSource: r.ContentSource.ToCSIRepresentation(),
AccessibilityRequirements: r.AccessibilityRequirements.ToCSIRepresentation(),
}
return req
}
func (r *ControllerCreateVolumeRequest) Validate() error {
if r.Name == "" {
return errors.New("missing Name")
}
if r.VolumeCapabilities == nil {
return errors.New("missing VolumeCapabilities")
}
if r.CapacityRange != nil {
if r.CapacityRange.LimitBytes == 0 && r.CapacityRange.RequiredBytes == 0 {
return errors.New(
"one of LimitBytes or RequiredBytes must be set if CapacityRange is set")
}
if r.CapacityRange.LimitBytes > 0 &&
r.CapacityRange.LimitBytes < r.CapacityRange.RequiredBytes {
return errors.New("LimitBytes cannot be less than RequiredBytes")
}
}
if r.ContentSource != nil {
if r.ContentSource.CloneID != "" && r.ContentSource.SnapshotID != "" {
return errors.New(
"one of SnapshotID or CloneID must be set if ContentSource is set")
}
}
return nil
}
// VolumeContentSource is snapshot or volume that the plugin will use to
// create the new volume. At most one of these fields can be set, but nil (andView on GitHub (pinned to 482b49bf1a)
Solutions
- Set at least one of RequiredBytes or LimitBytes to a positive byte value in the CapacityRange
- If no capacity constraint is intended, leave CapacityRange nil instead of passing an empty struct
- Check the config-to-bytes conversion for the volume size setting
Example fix
// before
req := &csi.ControllerCreateVolumeRequest{
Name: "vol-1",
VolumeCapabilities: caps,
CapacityRange: &csi.CapacityRange{}, // both zero -> error
}
// after
req := &csi.ControllerCreateVolumeRequest{
Name: "vol-1",
VolumeCapabilities: caps,
CapacityRange: &csi.CapacityRange{RequiredBytes: 10 * 1024 * 1024 * 1024},
} Defensive patterns
Strategy: validation
Validate before calling
func validateCapacity(req *csi.ControllerCreateVolumeRequest) error {
cr := req.CapacityRange
if cr != nil && cr.LimitBytes == 0 && cr.RequiredBytes == 0 {
return errors.New("CapacityRange set but both LimitBytes and RequiredBytes are zero")
}
return nil
} Type guard
func hasUsableCapacity(req *csi.ControllerCreateVolumeRequest) bool {
cr := req.CapacityRange
return cr == nil || cr.LimitBytes > 0 || cr.RequiredBytes > 0
} Try / catch
if err := req.Validate(); err != nil {
if strings.Contains(err.Error(), "LimitBytes or RequiredBytes") {
return fmt.Errorf("create refused: set a positive byte value or omit CapacityRange entirely: %w", err)
}
return err
} Prevention
- Convert human-readable sizes to bytes with a tested helper and reject zero results
- Pass nil CapacityRange when no size constraint is intended
- Add a unit test for each size configuration path to catch silent zero conversions
When it happens
Trigger: Setting CapacityRange to &csi.CapacityRange{} (or a struct populated from config where both size fields rendered as 0) and then calling ControllerCreateVolume.
Common situations: Config parsing that failed to convert a human size (e.g. "10Gi") into bytes, silently yielding zeros; template typos like required_bytes vs requiredBytes; callers copying the CapacityRange pointer without its values.
Related errors
- missing StagingTargetPath
- missing NodeID
- missing ExternalID
- missing Name
- max requested capacity (%s) less than or equal to current (%
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6e1e4291b175fb74.
Report an issue: GitHub.