hashicorp/nomad · error
requested capabilities not compatible with volume %q: %v
Error message
requested capabilities not compatible with volume %q: %v
What it means
This error is returned by the CSI client's ControllerExpandVolume when the storage plugin's controller responds with gRPC status InvalidArgument. It means the volume capabilities (access mode, access type, filesystem) in the expansion request were rejected as incompatible with the existing volume on the storage backend. The library maps the raw gRPC status code to this human-readable message so callers can distinguish capability mismatches from other expansion failures. The underlying plugin error text is appended for diagnostics.
Source
Thrown at plugins/csi/client.go:531
}
return err
}
func (c *client) ControllerExpandVolume(ctx context.Context, req *ControllerExpandVolumeRequest, opts ...grpc.CallOption) (*ControllerExpandVolumeResponse, error) {
if err := req.Validate(); err != nil {
return nil, err
}
if err := c.ensureConnected(ctx); err != nil {
return nil, err
}
exReq := req.ToCSIRepresentation()
resp, err := c.controllerClient.ControllerExpandVolume(ctx, exReq, opts...)
if err != nil {
code := status.Code(err)
switch code {
case codes.InvalidArgument:
return nil, fmt.Errorf(
"requested capabilities not compatible with volume %q: %v",
req.ExternalVolumeID, err)
case codes.NotFound:
err = fmt.Errorf("volume %q could not be found: %v", req.ExternalVolumeID, err)
case codes.FailedPrecondition:
err = fmt.Errorf("volume %q cannot be expanded online: %v", req.ExternalVolumeID, err)
case codes.OutOfRange:
return nil, fmt.Errorf(
"unsupported capacity_range for volume %q: %v", req.ExternalVolumeID, err)
case codes.Internal:
err = fmt.Errorf("controller plugin returned an internal error, check the plugin allocation logs for more information: %v", err)
default:
err = fmt.Errorf("controller plugin returned an error: %v", err)
}
return nil, err
}
return &ControllerExpandVolumeResponse{View on GitHub (pinned to 482b49bf1a)
Solutions
- Inspect the appended gRPC error detail to identify which capability field was rejected.
- Ensure the ControllerExpandVolumeRequest capability matches the volume's original creation capabilities exactly (access mode, mount volume/filesystem).
- Re-create the volume with the desired capabilities instead of expanding an incompatible one.
- Check the CSI plugin version/docs for capability restrictions on online expansion.
Example fix
// before
req := &csi.ControllerExpandVolumeRequest{
ExternalVolumeID: id,
CapacityRange: &csi.CapacityRange{RequiredBytes: newSize},
// capability omitted or changed from creation time
}
// after
req := &csi.ControllerExpandVolumeRequest{
ExternalVolumeID: id,
CapacityRange: &csi.CapacityRange{RequiredBytes: newSize},
VolumeCapability: originalCreationCapability, // same access mode + fs as at creation
} Defensive patterns
Strategy: try-catch
Validate before calling
if req.CapacityRange == nil || req.CapacityRange.RequiredBytes <= currentVol.CapacityBytes {
return fmt.Errorf("required bytes must be greater than current size %d", currentVol.CapacityBytes)
}
// ensure capability matches creation-time capability
if !reflect.DeepEqual(req.VolumeCapability, creationSpec.VolumeCapability) {
return fmt.Errorf("expansion capability must match original volume capability")
} Type guard
func isInvalidArgumentErr(err error) bool {
if err == nil { return false }
return strings.Contains(err.Error(), "requested capabilities not compatible with volume")
} Try / catch
resp, err := client.ControllerExpandVolume(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "requested capabilities not compatible with volume") {
// fix capability in the volume spec to match creation-time capability
return fmt.Errorf("fix volume capability: %w", err)
}
return err
} Prevention
- Store and reuse the exact VolumeCapability used at volume creation when expanding.
- Never change access mode or filesystem type between create and expand operations.
- Pin and test your CSI plugin version; capability validation rules can change between releases.
When it happens
Trigger: Calling ControllerExpandVolume (e.g. via Nomad's volume expansion path) with a ControllerExpandVolumeRequest whose VolumeCapability does not match how the volume was originally created, and the CSI plugin replies with codes.InvalidArgument.
Common situations: Changing the access mode (e.g. MULTI_NODE_READER_ONLY to SINGLE_NODE_WRITER) or filesystem type between volume creation and expansion; a plugin upgrade that changed capability validation; running expansion against a volume created by a different driver or with different mount options.
Related errors
- nil response from plugin.NodeExpandVolume
- CSI.ControllerExpandVolume: %v
- volume %q snapshot source %q is not compatible with these pa
- controller plugin returned an error: %v
- volume %q cannot be expanded while in use: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/cb762ab23f4dfe60.
Report an issue: GitHub.