{"record":{"id":"5d6bcf0fc66d6572","repo":"hashicorp/nomad","slug":"volume-q-cannot-be-expanded-online-v","errorCode":null,"errorMessage":"volume %q cannot be expanded online: %v","messagePattern":"volume %q cannot be expanded online: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/csi/client.go","lineNumber":537,"sourceCode":"\t\treturn nil, err\n\t}\n\tif err := c.ensureConnected(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\n\texReq := req.ToCSIRepresentation()\n\tresp, err := c.controllerClient.ControllerExpandVolume(ctx, exReq, opts...)\n\tif err != nil {\n\t\tcode := status.Code(err)\n\t\tswitch code {\n\t\tcase codes.InvalidArgument:\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"requested capabilities not compatible with volume %q: %v\",\n\t\t\t\treq.ExternalVolumeID, err)\n\t\tcase codes.NotFound:\n\t\t\terr = fmt.Errorf(\"volume %q could not be found: %v\", req.ExternalVolumeID, err)\n\t\tcase codes.FailedPrecondition:\n\t\t\terr = fmt.Errorf(\"volume %q cannot be expanded online: %v\", req.ExternalVolumeID, err)\n\t\tcase codes.OutOfRange:\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"unsupported capacity_range for volume %q: %v\", req.ExternalVolumeID, err)\n\t\tcase codes.Internal:\n\t\t\terr = fmt.Errorf(\"controller plugin returned an internal error, check the plugin allocation logs for more information: %v\", err)\n\t\tdefault:\n\t\t\terr = fmt.Errorf(\"controller plugin returned an error: %v\", err)\n\t\t}\n\t\treturn nil, err\n\t}\n\n\treturn &ControllerExpandVolumeResponse{\n\t\tCapacityBytes:         resp.GetCapacityBytes(),\n\t\tNodeExpansionRequired: resp.GetNodeExpansionRequired(),\n\t}, nil\n}\n\n// compareCapabilities returns an error if the 'got' capabilities aren't found","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/plugins/csi/client.go#L519-L555","documentation":"Returned when the CSI plugin's controller replies with gRPC status FailedPrecondition during ControllerExpandVolume. It means the storage backend cannot expand this volume while it is in its current state — typically online expansion of an attached/in-use volume is not supported. The library surfaces this as a distinct message so callers know the volume exists but cannot be grown right now.","triggerScenarios":"Calling ControllerExpandVolume on a volume that is currently attached/published and whose plugin or storage backend does not permit online (in-use) expansion, receiving codes.FailedPrecondition.","commonSituations":"Storage arrays that only support offline resize (volume must be detached first); block-attached volumes on backends requiring unmount before resize; plugin versions lacking ControllerExpandVolume support for published volumes.","solutions":["Detach/unpublish the volume from all nodes, expand it, then re-attach.","Stop the allocations using the volume so it can be taken offline during expansion.","Check whether the CSI plugin/backend supports online expansion and upgrade the plugin if a newer version adds it.","Consider migrating data to a volume type that supports online resize."],"exampleFix":"// before\n// expanding while volume is attached to a running allocation\nnomad volume status <id>  # shows allocations attached\nnomad volume expand <id> -capacity 100Gi\n// after\n# stop/detach first, then expand\nnomad job stop <job-using-volume>\nnomad volume expand <id> -capacity 100Gi\nnomad job run <job-using-volume>","handlingStrategy":"validation","validationCode":"// only expand volumes with no active claims/allocations\nif len(volume.Reads) > 0 || len(volume.Writes) > 0 {\n    return fmt.Errorf(\"volume %s is in use; detach before offline expansion\", volume.ID)\n}\n// check the plugin advertises expand capability\nif !pluginSupports(caps, csipbv1.ControllerServiceCapability_RPC_EXPAND_VOLUME) {\n    return fmt.Errorf(\"plugin does not support expansion\")\n}","typeGuard":"func isFailedPreconditionErr(err error) bool {\n    if err == nil { return false }\n    return strings.Contains(err.Error(), \"cannot be expanded online\")\n}","tryCatchPattern":"resp, err := client.ControllerExpandVolume(ctx, req)\nif err != nil {\n    if strings.Contains(err.Error(), \"cannot be expanded online\") {\n        // schedule: stop allocations -> expand -> restart\n        return scheduleOfflineExpansion(req.ExternalVolumeID, req.CapacityRange)\n    }\n    return err\n}","preventionTips":["Check the plugin's ControllerGetCapabilities for EXPAND_VOLUME support before offering expansion.","Consult backend documentation on online vs offline resize for your volume type.","Automate detach-expand-attach workflows for backends that require offline resize."],"tags":["csi","grpc","failed-precondition","online-expansion"],"backgroundTag":"volume-online-expand-not-supported","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"}