hashicorp/nomad · error
nil response from plugin.NodeExpandVolume
Error message
nil response from plugin.NodeExpandVolume
What it means
This error is returned by expandVolumeImpl in the CSI volume manager when the gRPC NodeExpandVolume call succeeds (err == nil) but the plugin returns a nil response. Nomad treats that as a plugin protocol violation, since a valid response must carry CapacityBytes.
Source
Thrown at client/pluginmanager/csimanager/volume.go:413
}
req := &csi.NodeExpandVolumeRequest{
ExternalVolumeID: remoteID,
CapacityRange: capacity,
Capability: capability,
TargetPath: v.targetForVolume(v.containerMountPoint, volID, allocID, usage),
StagingPath: stagingPath,
}
resp, err := v.plugin.NodeExpandVolume(ctx, req,
grpc_retry.WithPerRetryTimeout(DefaultMountActionTimeout),
grpc_retry.WithMax(3),
grpc_retry.WithBackoff(grpc_retry.BackoffExponential(100*time.Millisecond)),
)
if err != nil {
return 0, err
}
if resp == nil {
return 0, errors.New("nil response from plugin.NodeExpandVolume")
}
return resp.CapacityBytes, nil
}
func (v *volumeManager) stagingDirForVolume(root string, volNS, volID string, usage *UsageOptions) string {
return filepath.Join(root, StagingDirName, volNS, volID, usage.ToFS())
}
func (v *volumeManager) allocDirForVolume(root string, volID, allocID string) string {
return filepath.Join(root, AllocSpecificDirName, allocID, volID)
}
func (v *volumeManager) targetForVolume(root string, volID, allocID string, usage *UsageOptions) string {
return filepath.Join(root, AllocSpecificDirName, allocID, volID, usage.ToFS())
}
// ensureStagingDir attempts to create a directory for use when staging a volume
// and then validates that the path is not already a mount point for e.g anView on GitHub (pinned to 482b49bf1a)
Solutions
- Upgrade the CSI plugin/driver to a version with correct NodeExpandVolume support
- Retry the volume expansion; transient plugin failure may resolve
- Check plugin logs for panics or malformed responses during expansion
- Verify the driver is certified for the volume type being expanded
Defensive patterns
Strategy: retry
Type guard
func validExpandResp(resp *csi.NodeExpandVolumeResponse) bool { return resp != nil && resp.CapacityBytes > 0 } Try / catch
bytes, err := manager.expandVolumeImpl(ctx, req)
if err != nil && strings.Contains(err.Error(), "nil response from plugin.NodeExpandVolume") {
// retry expand; if persistent, restart/upgrade the CSI plugin
return retryExpandWithBackoff(ctx, req)
} Prevention
- Use certified, current CSI drivers that fully implement NodeExpandVolume
- Monitor plugin logs for panics during expansion
- Retry transient expand failures with backoff
- Test volume expansion workflows when upgrading CSI plugins
When it happens
Trigger: Calling volume expansion against a CSI plugin whose NodeExpandVolume RPC returns success with a nil response — malformed or non-conformant CSI plugin behavior.
Common situations: Buggy or partially implemented third-party CSI drivers, plugin crashes mid-RPC returning empty success, or driver versions that don't implement NodeExpandVolume correctly.
Related errors
- CSI.ControllerExpandVolume: %v
- requested capabilities not compatible with volume %q: %v
- controller plugin returned an error: %v
- %w: volume %q could not be found: %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/0916b96255555299.
Report an issue: GitHub.