{"record":{"id":"77a671c4b55b6252","repo":"hashicorp/nomad","slug":"csipluginconfig-plugintype-must-be-one-of-node","errorCode":null,"errorMessage":"CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \"%s\"","messagePattern":"CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \"(.+?)\"","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/structs.go","lineNumber":8413,"sourceCode":"\t// Validation for volumes\n\tfor idx, vm := range t.VolumeMounts {\n\t\tif _, ok := tg.Volumes[vm.Volume]; !ok {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Volume Mount (%d) references undefined volume %s\", idx, vm.Volume))\n\t\t}\n\n\t\tif err := vm.Validate(); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Volume Mount (%d) is invalid: \\\"%w\\\"\", idx, err))\n\t\t}\n\t}\n\n\t// Validate CSI Plugin Config\n\tif t.CSIPluginConfig != nil {\n\t\tif t.CSIPluginConfig.ID == \"\" {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"CSIPluginConfig must have a non-empty PluginID\"))\n\t\t}\n\n\t\tif !CSIPluginTypeIsValid(t.CSIPluginConfig.Type) {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"CSIPluginConfig PluginType must be one of 'node', 'controller', or 'monolith', got: \\\"%s\\\"\", t.CSIPluginConfig.Type))\n\t\t}\n\n\t\tif t.CSIPluginConfig.StagePublishBaseDir != \"\" && t.CSIPluginConfig.MountDir != \"\" &&\n\t\t\thelper.IsSubdirectory(t.CSIPluginConfig.MountDir, t.CSIPluginConfig.StagePublishBaseDir) {\n\t\t\tmErr.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))\n\t\t}\n\n\t\t// TODO: Investigate validation of the PluginMountDir. Not much we can do apart from check IsAbs until after we understand its execution environment though :(\n\t}\n\n\t// Validate default Identity\n\tif t.Identity != nil {\n\t\tif err := t.Identity.Validate(); err != nil {\n\t\t\tmErr.Errors = append(mErr.Errors, fmt.Errorf(\"Identity %q is invalid: %w\", t.Identity.Name, err))\n\t\t}\n\t}\n\n\t// Validate Identities","sourceCodeStart":8395,"sourceCodeEnd":8431,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/structs.go#L8395-L8431","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ncsi_plugin {\n  id   = \"aws-efs0\"\n  type = \"Node\"\n}\n// after\ncsi_plugin {\n  id   = \"aws-efs0\"\n  type = \"node\"\n}","handlingStrategy":"validation","validationCode":"var validCSIPluginTypes = map[string]bool{\"node\": true, \"controller\": true, \"monolith\": true}\nif cfg != nil && !validCSIPluginTypes[cfg.Type] {\n    return fmt.Errorf(\"csi_plugin type %q must be node, controller, or monolith\", cfg.Type)\n}","typeGuard":"func csiPluginTypeValid(t string) bool {\n    return t == \"node\" || t == \"controller\" || t == \"monolith\"\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["nomad","csi","validation","jobspec"],"backgroundTag":"invalid-enum-value","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}