{"record":{"id":"a79930b6af5b43d1","repo":"hashicorp/nomad","slug":"capacity-max-d-cannot-be-less-than-existing-pro","errorCode":null,"errorMessage":"capacity_max (%d) cannot be less than existing provisioned capacity (%d)","messagePattern":"capacity_max \\((.+?)\\) cannot be less than existing provisioned capacity \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/host_volumes.go","lineNumber":198,"sourceCode":"\tif len(existing.Allocations) > 0 {\n\t\tallocIDs := helper.ConvertSlice(existing.Allocations,\n\t\t\tfunc(a *AllocListStub) string { return a.ID })\n\t\tmErr = multierror.Append(mErr, fmt.Errorf(\n\t\t\t\"cannot update a volume in use: claimed by allocs (%s)\",\n\t\t\tstrings.Join(allocIDs, \", \")))\n\t}\n\n\tif hv.NodeID != \"\" && hv.NodeID != existing.NodeID {\n\t\tmErr = multierror.Append(mErr, errors.New(\"node ID cannot be updated\"))\n\t}\n\tif hv.NodePool != \"\" && hv.NodePool != existing.NodePool {\n\t\tmErr = multierror.Append(mErr, errors.New(\"node pool cannot be updated\"))\n\t}\n\n\tif hv.RequestedCapacityMaxBytes > 0 &&\n\t\thv.RequestedCapacityMaxBytes < existing.CapacityBytes {\n\t\tmErr = multierror.Append(mErr, fmt.Errorf(\n\t\t\t\"capacity_max (%d) cannot be less than existing provisioned capacity (%d)\",\n\t\t\thv.RequestedCapacityMaxBytes, existing.CapacityBytes))\n\t}\n\n\treturn mErr.ErrorOrNil()\n}\n\nconst DefaultHostVolumePlugin = \"default\"\n\n// CanonicalizeForCreate is called in the RPC handler to ensure we call client\n// RPCs with correctly populated fields from the existing volume, even if the\n// RPC request includes otherwise valid zero-values. This method should be\n// called on request objects or a copy, never on a state store object directly.\nfunc (hv *HostVolume) CanonicalizeForCreate(existing *HostVolume, now time.Time) {\n\tif existing == nil {\n\t\thv.ID = uuid.Generate()\n\t\tif hv.PluginID == \"\" {\n\t\t\thv.PluginID = DefaultHostVolumePlugin\n\t\t}","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/host_volumes.go#L180-L216","documentation":"ValidateUpdate rejects shrinking a host volume's capacity_max below the capacity already provisioned on the node. If RequestedCapacityMaxBytes is positive and lower than existing.CapacityBytes, storage would be over-committed, so the update fails.","triggerScenarios":"Updating a host volume with RequestedCapacityMaxBytes > 0 that is smaller than the node's current CapacityBytes for that volume (via the volume update path / validateVolumeUpdate).","commonSituations":"Operator tries to cap usage below what the CSI/Node reports as already provisioned; typo in byte count (e.g. GiB vs MiB); node resized independently of Nomad.","solutions":["Raise RequestedCapacityMaxBytes to at least existing.CapacityBytes","Set RequestedCapacityMaxBytes to 0 (unset) to leave the cap unchanged","Rescale the actual storage on the node/CSI provider first, then update the volume"],"exampleFix":"// before\nRequestedCapacityMaxBytes: 5 * 1024 * 1024 * 1024 // 5GiB < provisioned\n// after\nRequestedCapacityMaxBytes: 20 * 1024 * 1024 * 1024 // >= existing capacity","handlingStrategy":"validation","validationCode":"if hv.RequestedCapacityMaxBytes > 0 && hv.RequestedCapacityMaxBytes < existing.CapacityBytes {\n  return fmt.Errorf(\"capacity_max %d below provisioned %d\", hv.RequestedCapacityMaxBytes, existing.CapacityBytes)\n}","typeGuard":null,"tryCatchPattern":"if err := updateVolume(hv); err != nil {\n  if strings.Contains(err.Error(), \"cannot be less than existing provisioned capacity\") {\n    hv.RequestedCapacityMaxBytes = existing.CapacityBytes\n  }\n}","preventionTips":["Fetch current capacity via volume status before setting capacity_max","Use explicit unit math (GiB constants) to avoid byte-count typos","Only set capacity_max when intentionally resizing"],"tags":["nomad","validation","host-volume","capacity"],"backgroundTag":"capacity-shrink-not-allowed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}