hashicorp/nomad · error
CSIPluginConfig PluginType must be one of 'node', 'controlle
Error message
CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: "%s"
What it means
Task.Validate checks CSIPluginConfig.Type against CSIPluginTypeIsValid, which accepts only 'node', 'controller', or 'monolith'. Any other string (or empty) fails this error. The plugin type tells Nomad which capabilities (controller/node) the plugin exposes.
Source
Thrown at nomad/structs/structs.go:8413
// Validation for volumes
for idx, vm := range t.VolumeMounts {
if _, ok := tg.Volumes[vm.Volume]; !ok {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Volume Mount (%d) references undefined volume %s", idx, vm.Volume))
}
if err := vm.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Volume Mount (%d) is invalid: \"%w\"", idx, err))
}
}
// Validate CSI Plugin Config
if t.CSIPluginConfig != nil {
if t.CSIPluginConfig.ID == "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig must have a non-empty PluginID"))
}
if !CSIPluginTypeIsValid(t.CSIPluginConfig.Type) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \"%s\"", t.CSIPluginConfig.Type))
}
if t.CSIPluginConfig.StagePublishBaseDir != "" && t.CSIPluginConfig.MountDir != "" &&
helper.IsSubdirectory(t.CSIPluginConfig.MountDir, t.CSIPluginConfig.StagePublishBaseDir) {
mErr.Errors = append(mErr.Errors, fmt.Errorf("CSIPluginConfig StagePublishBaseDir must not be a subdirectory of MountDir, got: StagePublishBaseDir=\"%s\" MountDir=\"%s\"", t.CSIPluginConfig.StagePublishBaseDir, t.CSIPluginConfig.MountDir))
}
// TODO: Investigate validation of the PluginMountDir. Not much we can do apart from check IsAbs until after we understand its execution environment though :(
}
// Validate default Identity
if t.Identity != nil {
if err := t.Identity.Validate(); err != nil {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Identity %q is invalid: %w", t.Identity.Name, err))
}
}
// Validate IdentitiesView on GitHub (pinned to 482b49bf1a)
Solutions
- Change type to one of: "node", "controller", or "monolith"
- Use "monolith" if the plugin provides both controller and node capabilities
- Check the plugin's documentation for which CSI controller/node capabilities it implements and pick accordingly
Example fix
// before
csi_plugin {
id = "aws-efs0"
type = "Node"
}
// after
csi_plugin {
id = "aws-efs0"
type = "node"
} Defensive patterns
Strategy: validation
Validate before calling
var validCSIPluginTypes = map[string]bool{"node": true, "controller": true, "monolith": true}
if cfg != nil && !validCSIPluginTypes[cfg.Type] {
return fmt.Errorf("csi_plugin type %q must be node, controller, or monolith", cfg.Type)
} Type guard
func csiPluginTypeValid(t string) bool {
return t == "node" || t == "controller" || t == "monolith"
} Prevention
- Use HCL job specs with autocomplete/lint to restrict type to enum values
- Copy the exact strings 'node', 'controller', 'monolith' — case sensitive
- Check plugin docs for its capabilities before choosing the type
When it happens
Trigger: csi_plugin block with type set to a misspelled or unsupported value like "plugins", "Node", "storage", or omitted entirely (empty string) in a task's csi_plugin config.
Common situations: Typos or wrong casing in the jobspec type argument; copying examples from other orchestrators (Kubernetes/CSIDriver) that use different type vocabularies; older Nomad jobspecs written before the field was enforced.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- CSIPluginConfig must have a non-empty PluginID
- missing secret ID
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
- CSI.ControllerDetachVolume: VolumeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/77a671c4b55b6252.
Report an issue: GitHub.