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 (and

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set at least one of RequiredBytes or LimitBytes to a positive byte value in the CapacityRange
  2. If no capacity constraint is intended, leave CapacityRange nil instead of passing an empty struct
  3. 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

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


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/6e1e4291b175fb74. Report an issue: GitHub.