hashicorp/nomad · error
PluginID is required
Error message
PluginID is required
What it means
err("PluginID is required") is produced by ClientCSINodeExpandVolumeRequest.Validate when the PluginID field is empty. Per the source comment these checks exist mainly to catch programmer error, since a client CSI node expand request without a plugin ID is meaningless. The error is joined via errors.Join with other validation failures.
Source
Thrown at client/structs/csi.go:481
PluginID string // ID of the plugin that manages the volume (required)
VolumeID string // ID of the volume to be expanded (required)
VolumeNamespace string // Namespace of the volume to be expanded (required)
ExternalID string // External ID of the volume to be expanded (required)
// Capacity range (required) to be sent to the node plugin
Capacity *csi.CapacityRange
// Claim currently held for the allocation (required)
// used to determine capabilities and the mount point on the client
Claim *structs.CSIVolumeClaim
}
func (req *ClientCSINodeExpandVolumeRequest) Validate() error {
var err error
// These should not occur during normal operations; they're here
// mainly to catch potential programmer error.
if req.PluginID == "" {
err = errors.Join(err, errors.New("PluginID is required"))
}
if req.VolumeID == "" {
err = errors.Join(err, errors.New("VolumeID is required"))
}
if req.ExternalID == "" {
err = errors.Join(err, errors.New("ExternalID is required"))
}
if req.Claim == nil {
err = errors.Join(err, errors.New("Claim is required"))
} else if req.Claim.AllocationID == "" {
err = errors.Join(err, errors.New("Claim.AllocationID is required"))
}
return err
}
type ClientCSINodeExpandVolumeResponse struct {
CapacityBytes int64
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Set PluginID from the volume's plugin info before calling the expand RPC
- Verify the CSI plugin is registered/running on the node and its ID is resolved
- Use errors.Is / string matching on Validate's joined error to identify the missing field
- Add a pre-call check that req.PluginID != ""
Example fix
// before
req := &cstructs.ClientCSINodeExpandVolumeRequest{VolumeID: volID, ExternalID: extID}
// after
req := &cstructs.ClientCSINodeExpandVolumeRequest{PluginID: pluginID, VolumeID: volID, ExternalID: extID} Defensive patterns
Strategy: validation
Validate before calling
if err := req.Validate(); err != nil { return err }
if req.PluginID == "" { return errors.New("PluginID must be resolved before node expand") } Try / catch
if err := req.Validate(); err != nil {
if strings.Contains(err.Error(), "PluginID is required") {
// re-resolve the CSI plugin ID for the node and rebuild the request
return resolvePluginAndRetry()
}
return err
} Prevention
- Always resolve and set PluginID from the volume's plugin info before the RPC
- Verify the CSI plugin is registered on the node before expanding volumes
- Run Validate() early and log the joined error for full diagnosis
- Add unit tests asserting all request fields are populated
When it happens
Trigger: Submitting a ClientCSINodeExpandVolumeRequest with PluginID == "" — e.g. a code path constructing the request that failed to look up the CSI plugin ID for the node.
Common situations: Programmer error building the request, plugin deregistration between volume claim and expand so the plugin ID lookup returns empty, or copying the request struct without setting PluginID.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1e2e27a106c26937.
Report an issue: GitHub.