hashicorp/nomad · error
node %s is not feasible for volume
Error message
node %s is not feasible for volume
What it means
When a NodeID is given, the node must satisfy the volume's constraints — including an implicit constraint that the node runs a host-volume plugin with the volume's PluginID (attr.plugins.host_volume.<plugin>.version is_set) plus any user constraints. If checker.Feasible(node) fails, Create is rejected with this message.
Source
Thrown at nomad/host_volume_endpoint.go:557
semverCache: make(map[string]feasible.VerConstraints),
}
constraints := []*structs.Constraint{{
LTarget: fmt.Sprintf("${attr.plugins.host_volume.%s.version}", vol.PluginID),
Operand: "is_set",
}}
constraints = append(constraints, vol.Constraints...)
checker := feasible.NewConstraintChecker(ctx, constraints)
if vol.NodeID != "" {
node, err := snap.NodeByID(nil, vol.NodeID)
if err != nil {
return nil, err
}
if node == nil {
return nil, fmt.Errorf("no such node %s", vol.NodeID)
}
if ok := checker.Feasible(node); !ok {
return nil, fmt.Errorf("node %s is not feasible for volume", vol.NodeID)
}
vol.NodePool = node.NodePool
return node, nil
}
poolFilterFn, err := v.enterpriseNodePoolFilter(snap, vol)
if err != nil {
return nil, err
}
var iter memdb.ResultIterator
if vol.NodePool != "" {
if !poolFilterFn(vol.NodePool) {
return nil, fmt.Errorf("namespace %q does not allow volumes to use node pool %q",
vol.Namespace, vol.NodePool)
}
iter, err = snap.NodesByNodePool(nil, vol.NodePool)View on GitHub (pinned to 482b49bf1a)
Solutions
- Verify the host-volume plugin is running on the target node and its plugin_id matches the volume's PluginID (`nomad node status <id>` shows attributes).
- Remove or relax the constraints on the volume that the node cannot satisfy.
- Omit NodeID and let placement find a feasible node automatically.
Example fix
// before
hv := &api.HostVolume{ PluginID: "docker-plugin", NodeID: nodeId, Constraints: [{"${node.datacenter}", "=", "dc2"}] }
// after — node is in dc1
hv := &api.HostVolume{ PluginID: "docker-plugin", NodeID: nodeId } Defensive patterns
Strategy: validation
Validate before calling
node, _, err := client.Nodes().Info(vol.NodeID, nil)
if err != nil { return err }
attr, ok := node.Attributes[fmt.Sprintf("plugins.host_volume.%s.version", vol.PluginID)]
if !ok {
return fmt.Errorf("node %s lacks host_volume plugin %q", vol.NodeID, vol.PluginID)
} Prevention
- Confirm the host-volume plugin is running on pinned nodes before creating volumes.
- Match plugin_id exactly against the client's plugin configuration.
- Check volume constraints against node attributes/datacenter before pinning.
When it happens
Trigger: Creating a host volume pinned to a node that lacks the CSI/host-volume plugin driver, runs an incompatible plugin version, or fails an explicit constraint in vol.Constraints (e.g. datacenter, meta labels, OS).
Common situations: Plugin not started on that client or plugin_id typo; wrong plugin version installed; constraint referencing node meta attributes that the target node doesn't have; volume spec copied from another node with different attributes.
Related errors
- no node meets constraints: %d nodes had existing volume, %d
- no such node %s
- invalid constraint: %v
- Constraint %d has disallowed Operand at task level: %s
- ErrPluginNotExists
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/b4f3e2ee2d9ed53b.
Report an issue: GitHub.