hashicorp/nomad · error
volume is currently unschedulable
Error message
volume is currently unschedulable
What it means
ErrCSIVolumeUnschedulable is returned when a volume claim is requested but the volume is not currently schedulable for the requested access mode — its plugin is unhealthy, the node is down, or read/write scheduling capacity is zero (ReadSchedulable/WriteSchedulable returns false). The state store refuses the claim because the volume cannot be served.
Source
Thrown at nomad/structs/errors.go:92
ErrResultPaginatorCreation = errors.New(errResultPaginatorCreation)
ErrUnknownNode = errors.New(ErrUnknownNodePrefix)
ErrDeploymentTerminalNoCancel = errors.New(errDeploymentTerminalNoCancel)
ErrDeploymentTerminalNoFail = errors.New(errDeploymentTerminalNoFail)
ErrDeploymentTerminalNoPause = errors.New(errDeploymentTerminalNoPause)
ErrDeploymentTerminalNoPromote = errors.New(errDeploymentTerminalNoPromote)
ErrDeploymentTerminalNoResume = errors.New(errDeploymentTerminalNoResume)
ErrDeploymentTerminalNoUnblock = errors.New(errDeploymentTerminalNoUnblock)
ErrDeploymentTerminalNoRun = errors.New(errDeploymentTerminalNoRun)
ErrDeploymentTerminalNoSetHealth = errors.New(errDeploymentTerminalNoSetHealth)
ErrDeploymentRunningNoUnblock = errors.New(errDeploymentRunningNoUnblock)
ErrCSIClientRPCIgnorable = errors.New("CSI client error (ignorable)")
ErrCSIClientRPCRetryable = errors.New("CSI client error (retryable)")
ErrCSIVolumeMaxClaims = errors.New("volume max claims reached")
ErrCSIVolumeUnschedulable = errors.New("volume is currently unschedulable")
ErrCSIPluginInUse = errors.New("plugin in use")
)
// IsErrNoLeader returns whether the error is due to there being no leader.
func IsErrNoLeader(err error) bool {
return err != nil && strings.Contains(err.Error(), errNoLeader)
}
// IsErrNoRegionPath returns whether the error is due to there being no path to
// the given region.
func IsErrNoRegionPath(err error) bool {
return err != nil && strings.Contains(err.Error(), errNoRegionPath)
}
// IsErrTokenNotFound returns whether the error is due to the passed token not
// being resolvable.
func IsErrTokenNotFound(err error) bool {
return err != nil && strings.Contains(err.Error(), errTokenNotFound)
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Check 'nomad plugin status <plugin>' and 'nomad node status' — restore plugin health or bring the node back, then retry the claim
- Verify the volume spec's requested capabilities match what the plugin actually advertises (nomad volume inspect)
- Fix plugin/controller configuration so the volume is marked schedulable (correct CSI endpoint, healthy controller)
- If the volume belongs to a drained/dead node, re-create the volume pointing at a healthy node's plugin
Example fix
// before # volume spec requires write access, but plugin advertises only read access_mode = "single-node-writer" // after # match capabilities to the plugin's advertised CSI capabilities access_mode = "single-node-reader-only" attachment_mode = "file-system" # or fix the plugin so it supports the requested capability
Defensive patterns
Strategy: validation
Validate before calling
vol, _, err := client.CSIVolumes().Info(volID, nil)
if err != nil || vol == nil || len(vol.NodesHealthy) == 0 || vol.Schedulable == false {
return fmt.Errorf("volume %s not schedulable: plugin/node unhealthy", volID)
} Type guard
func volumeSchedulable(vol *api.CSIVolume, write bool) bool {
if vol == nil { return false }
if write { return vol.Schedulable && len(vol.NodesHealthy) > 0 }
return vol.Schedulable
} Try / catch
err := claimVolume(volID, allocID)
if err != nil && strings.Contains(err.Error(), structs.ErrCSIVolumeUnschedulable.Error()) {
return fmt.Errorf("volume %s unschedulable; check plugin health and node status", volID)
} Prevention
- Monitor CSI plugin health (nomad plugin status) and node eligibility before scheduling volume jobs
- Match requested access_mode/capabilities to what the plugin advertises
- Keep the storage controller reachable so volumes stay marked schedulable
- Drain/nodes handling: recreate the volume on a healthy node after node loss
When it happens
Trigger: CSIVolume.Claim (via structs.CSIVolume.ValidateRequest at csi.go:629/659) when v.ReadSchedulable() or v.WriteSchedulable() is false — e.g. the CSI plugin's health is unhealthy, Schedulable is false, or all topologies/nodes serving the volume are unavailable.
Common situations: CSI plugin on the node is unhealthy or the node was drained; storage controller reports the volume as unavailable; plugin capability/Topology mis-match declared in the volume spec; after a node failure the volume has zero schedulable nodes.
Related errors
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
- CSI.ControllerDetachVolume: VolumeID is required
- CSI.ControllerDetachVolume: ClientCSINodeID is required
- CSI.NodeDetachVolume: PluginID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/4ed44df7f31e4b13.
Report an issue: GitHub.